当前位置: 首页 > news >正文

nodejs+wasm+rust debug及性能分析

文章目录

    • 背景
    • v8引擎自带的profile
    • linux的perf采集
    • wasm三方库性能分析
      • 编译debug版本wasm
      • rust程序debug调试
        • 异常模型
        • 正常模型
        • 结论
        • 优化

参考
Node使用火焰图优化CPU爆涨 - 掘金
【Node.js丨主题周】理解perf 与火焰图-腾讯云开发者社区-腾讯云
Easy profiling for Node.js Applications | Node.js
Diagnostics - Flame Graphs | Node.js
perf性能分析工具使用分享

背景

一个node服务在处理模型的时候,发现超时了,并且超过了3分钟的上限触发了报警。行吧,一般来说十几秒足够处理了,初步定位是mikktspace-wasm库的性能问题。

wasm正逐渐走进我们的程序生活,不少计算库都在用高性能语言重写,并通过wasm作为第三方包提供能力。例如博主最近用到的渲染相关的计算包,基本都是用c++和rust实现的,然后web端直接调用wasm即可。

写这篇博客呢,是因为博主一开始只是定位到三方库有问题就暂停了,毕竟是做后端的,也是存在一定的认知障碍吧,对不熟的东西也存在敬畏之心。然而根因不找到实在是难受,一路debug和性能分析下来,回头看看也没那么难。希望以后遇到类似的问题也可以乘风破浪,一路追下去,技术都是相通的,不应该存在壁垒。

v8引擎自带的profile

1、运行程序并采集
node --prof index.js xxx
v8会自动采集,并生成isolate-xxx文件
2、生成txt
node --prof-process isolate-xxx > processed.txt
vim直接打开,就可以查看采集的结果。采集结果分析参考以上链接。
3、查看火焰图npm install -g flamebearer
node --prof-process --preprocess -j isolate-xxx | flamebearer安装flamebearer,并执行上面的命令,会自动打开浏览器,查看生成的火焰图。

image.png

注意
运行node程序需要带两个参数:
–perf-basic-prof


通过--perf-basic-prof或 --perf-basic-prof-only-functions我们都可以启动支持
perf_events 的Node.js 应用程序。
--perf-basic-prof-only-functions产生较少的输出,因此它是开销最小的选项。
生成的文件在/tmp/perf-PID.map

–interpreted-frames-native-stack

Node.js 8.x 及更高版本对 V8 引擎中的 JavaScript 编译管道进行了新的优化,这有时会导致
性能无法访问函数名称/引用。使用以上参数可以解决。

linux的perf采集

1、perf采集
perf record -F 99 -g -- node --perf-basic-prof-only-functions index.js会在本地目录生成perf.data文件。2、生成火焰图
perf script | /home/xxx/FlameGraph/stackcollapse-perf.pl | /home/xxx/FlameGraph/flamegraph.pl > perf.svg下载FlameGraph项目,然后使用该项目提供的脚本生成火焰图即可。3、浏览器打开
python -m http.server 8000
浏览器访问ip:8000/perf.svg即可4、运行的时候查看cpu占用
perf top -p pid

使用js的三方库生成火焰图

1、采集perf (同上)
2、安装stackvis库
npm install -g stackvis3、script解析perf.data
perf script > perf.out4、生成火焰图的html
stackvis perf < perfs.out > flamegrap.htm5、浏览器查看(同上)

image.png

wasm三方库性能分析

如上所示,有些库使用wasm,导致只能看到库函数占用了97%的cpu,但是却看不到细节。针对这种情况可以考虑编译对应第三方库版本的debug版wasm文件,替换一下,重新采样。

编译debug版本wasm

例如:https://github.com/donmccurdy/mikktspace-wasm 这个库,是用rust编译成wasm的
(1)安装rust环境
https://developer.mozilla.org/zh-CN/docs/WebAssembly/Rust_to_Wasm
(2)编译debug版本

1、编译target为nodejs,对应commonjs标准
~/.cargo/bin/wasm-pack build --dev --target nodejs -d ./pkg/main --out-name mikktspace_main解释:--dev: 编译debug版本-d : 指定输入结果目录,设置为pkg/main--out-name: 指定生成的文件名前缀,wasm文件会自动加上_bg.wasm后缀2、编译target为bundler,对应打包工具的导入标准
~/.cargo/bin/wasm-pack build --dev -d ./pkg/bundler --out-name mikktspace_module3、查看编译的wasm是否是debug的(1)安装wabtsudo pacman -Si wabtwabt自带的有wasm-objdump,可以查看wasm的头信息(2)wasm-objdump -h mikktspace_main_bg.wasmmikktspace_main_bg.wasm:        file format wasm 0x1Sections:Type start=0x0000000e end=0x000000fa (size=0x000000ec) count: 35Import start=0x00000100 end=0x00000268 (size=0x00000168) count: 7Function start=0x0000026e end=0x00000542 (size=0x000002d4) count: 722Table start=0x00000548 end=0x0000054d (size=0x00000005) count: 1Memory start=0x00000553 end=0x00000556 (size=0x00000003) count: 1Global start=0x0000055c end=0x00000565 (size=0x00000009) count: 1Export start=0x0000056b end=0x000005fb (size=0x00000090) count: 7Elem start=0x00000601 end=0x00000663 (size=0x00000062) count: 1Code start=0x00000669 end=0x00048a07 (size=0x0004839e) count: 722Data start=0x00048a0d end=0x0004d858 (size=0x00004e4b) count: 1Custom start=0x0004d85e end=0x0005b3f4 (size=0x0000db96) "name"Custom start=0x0005b3fa end=0x0005b475 (size=0x0000007b) "producers"Custom start=0x0005b47b end=0x0005b4a7 (size=0x0000002c) "target_features"可以看到没有debuginfo信息。4、配置cargo.toml
参考:https://rustwasm.github.io/docs/wasm-pack/cargo-toml-configuration.html[package.metadata.wasm-pack.profile.dev.wasm-bindgen]
dwarf-debug-info = false5、重新编译并查看
Custom start=0x00062694 end=0x0014bc2d (size=0x000e9599) ".debug_info"多了一些debuginfo信息。

(3)替换node_moudles中的mikktspace/dist下的main和module目录
(4)重新perf采集数据,生成svg
image.png
成功采集到mikktspace这个库的调用栈以及cpu耗时。

(5)对比正常和异常情况下的火焰图

正常
image.png
相比上面的火焰图,可以发现正常的火焰图:

  1. cpu耗时分布较合理
  2. 无长时间耗时函数分布
  3. 异常火焰图耗时较久的函数DegenEpilogue在正常火焰图中并没有。

因此重点看下DegenEpilogue函数即可。

rust程序debug调试

参考:https://github.com/fucking-translation/blog/blob/main/src/lang/rust/14-%E4%BD%BF%E7%94%A8GDB%E8%B0%83%E8%AF%95Rust%E5%BA%94%E7%94%A8.md

1、编译debug版本
cargo默认编译出来的就是debug版本。指定编程生成的程序名为debug
cargo build --example debug2、rust-gdb调试
rust-gdb调试指令和gdb一样。
(1) 进入gdb
rust-gdb debug
(2) 设置断点
b xxx.rs:10(3) 开启可视化
layout src
如果页面乱了,ctrl+l 可以恢复代码页面(4) 调试
n : 下一步
s : 进入函数内部
c: 运行到下一个断点
异常模型

1、generateTspace部分,iNrActiveGroup = 19w,循环19w次,速度较快,10s执行完整个函数。
2、运行到DegenEpilogue, iNrTrianglesIn = 24w,
while t < iTotTris {} 这个循环耗时90s

// iDegenTriangles = 32412
// iDegenTriangles代表不合法的三角形面
iNrTrianglesIn = iTotTris - iDegenTriangles;

while t < iNrTrianglesIn {} 不耗时

正常模型

1、generateTspace部分,iNrActiveGroup = 172w,16s运行完整个函数
2、运行到DegenEpilogue, iNrTrianglesIn = 58w
while t < iTotTris {} 这个循环没走
原因是不符合whilet条件,t= iTotTris ,关键就在上一步传过来的iNrTrianglesIn和iTotTris

// iDegenTriangles = 0
// iDegenTriangles代表不合法的三角形面
iNrTrianglesIn = iTotTris - iDegenTriangles;

while t < iNrTrianglesIn {} 不耗时

结论

异常的模型中,不合法三角形的数量较多,需要通过DegenEpilogue函数进行辅助处理。正常的模型因为不合法三角形面数量较少,因此不需要进行DegenEpilogue函数处理。

mikktspace计算切面算法有多种语言实现,其中rust程序和c++程序对比来说,c++使用了二分来提升性能,rust和c程序均采用遍历的方式。可以考虑使用hash表减少循环层数或者二分提升查询性能。

mikktspace的c++库:https://github.com/naetherm/mikktspace
mikktspace的c库:https://github.com/mmikk/MikkTSpace

优化

rust程序中,存在双层循环如下:

// iTotTris - t = 3w
while t < iTotTris {// iNrTrianglesIn * 3 = 72wwhile bNotFound && j < 3i32 * iNrTrianglesIn {}
}双层循环情况下,性能较差。内部的循环使用hash表代替,直接通过key去获取。优化后单次循环耗时从ms级
优化到ns级。优化前耗时:90s
优化后耗时:27ms

end

相关文章:

nodejs+wasm+rust debug及性能分析

文章目录 背景v8引擎自带的profilelinux的perf采集wasm三方库性能分析编译debug版本wasmrust程序debug调试异常模型正常模型结论优化 参考 Node使用火焰图优化CPU爆涨 - 掘金 【Node.js丨主题周】理解perf 与火焰图-腾讯云开发者社区-腾讯云 Easy profiling for Node.js Applic…...

IP证书针对公网IP签发

很多项目应用需要采用IP地址数据桥接访问&#xff0c;这种情况下需要确保数据安全性及信任不被劫持的情况下&#xff0c;需要使用给IP地址增加数字证书进行保护。针对这种情况下我们对公网IP地址申请SSL证书做了详细的介绍&#xff0c;让我们可以更快地了解如何用IP地址去申请S…...

SpringBoot-集成Minio

官方文档&#xff1a;Kubernetes 的 MinIO 对象存储 — MinIO Object Storage for Kubernetes 一、简介 Minio 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口&#xff0c;非常适合于存储大容量非结构化的数据&#xff0c;例如图片、视频…...

【ML】cheatsheet

LR 原理与面试题目DT, Adaboost, GBDT, xgboost 原理 细节 与 例子 https://www.cnblogs.com/createMoMo/p/12635709.html xgboost挺详细的算法原理与例子 https://zhuanlan.zhihu.com/p/660468945 着重lightgbm就xgboost的改善方向 https://zhuanlan.zhihu.com/p/366952043机器…...

【字符串】【将字符数组转为字符串】Leetcode 122 路径加密

【将字符数组转为字符串】Leetcode 122 路径加密 解法1 在Java中&#xff0c;char数组没有直接的toString()方法来将其转换为字符串。如果你想将char数组转换为字符串&#xff0c;可以使用String类的构造函数来实现&#xff1a; ⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐…...

网络基础知识100问

1.什么是链接? 链接是指两个设备之间的连接。它包括用于一个设备能够与另一个设备通信的电缆类型和协议。 2.OSI 参考模型的层次是什么? 有 7 个 OSI 层&#xff1a;物理层&#xff0c;数据链路层&#xff0c;网络层&#xff0c;传输层&#xff0c;会话层&#xff0c;表示…...

女孩子就是要打扮漂亮,让童年不留遗憾

好的衣服当然要分享给好看的人啦&#xff01; 百搭圆领卫衣&#xff0c;经典版型不挑人穿 复合奥利绒面料&#xff0c;罗纹收口设计 时尚百搭怎么穿都好看 单穿内搭都可以 卡通鹅真的好可爱 宝贝穿上去真的元气满满哦...

实现目录数据的上移(up)、下移(down)、置顶(top)、置底(bottom)的操作

ApiOperation("8-15 交接班-标签设置排序")ApiImplicitParams({ApiImplicitParam(name "id", value "id", dataType "string", required true),ApiImplicitParam(name "orgnCode", value "机构代码", dataT…...

Ubuntu 常用命令

文章目录 Linux 目录结构常用命令ls&#xff1a;查看目录内容pwd&#xff1a;查看当前目录绝对路径cd&#xff1a;切换目录mkdir&#xff1a;创建目录rm&#xff1a;删除文件/目录touch&#xff1a;创建空文件mv&#xff1a;移动和重命名文件/目录cp&#xff1a;复制粘贴cat&am…...

如何空手套白狼?一口气省7K再抓住一个7K起步的工作?

今日话题&#xff0c;教你如何省七千再得到一个七千起步的技能&#xff01;现在网络行业已经是全世界重点发展的目标&#xff0c;开发行业更是各个企业重点培养&#xff0c;但是在学校教的网络知识太基础太老掉牙&#xff1f;报班随便就是小一万该如何是好呢&#xff1f;解决方…...

电脑主机如何选择内存条

选择计算机主机的内存模块&#xff08;内存条&#xff09;通常需要考虑以下因素&#xff1a; 类型和代数&#xff08;DDR3、DDR4、DDR5等&#xff09;&#xff1a;您的主板和处理器支持的内存类型非常重要。确保内存条的类型与您的主板和处理器兼容。 容量&#xff1a;内存容量…...

计算机考研自命题(5)

1、C语言–求和 1、展开式求和。输入一个实数x&#xff0c;计算并输出下式的和&#xff0c;直到最后一项的绝对值小于0.00001.计算结果保留2位小数&#xff0c;试编程。 S x x/2&#xff01; x/3&#xff01; … /* 算法思想&#xff1a;定义一个求阶乘的函数fact(), 头文件调…...

【原创】c语言4种字符串函数的代码测试

c语言4种字符串函数的代码测试 1.字符串拼接strcat [contact] 2.字符串复制strcpy 3.带参数的字符串复制strncpy 4.字符串比较strcmp&#xff1a;比第一个不同字母的ascii码&#xff0c;如acb>abc #include<stdio.h> #include<string.h>int main() {char s1[]&…...

扩散模型学习——代码学习

文章目录 引言正文UNet网络结构训练方法DDPM采样方法讲解Context上下文信息添加DDIM的方法详解 总结参考 引言 这是第一次接触扩散模型&#xff0c;为了学习&#xff0c;这里好好分析一下他的代码 正文 UNet网络结构 这部分主要是定义一下网络结构&#xff0c;以及相关的网…...

redis 数据结构

一、为什么要扒一下底层技术 首先我是一个解决方案工程师&#xff0c;为什么要看redis底层的设计呢&#xff1f;总结下来分几点&#xff1a; 1. 让系统跑起来更放心 2. 面试中可以对跟对面的牛马侃大山、吹&#x1f42e; 3. 虚一点&#xff0c;举一反三&#xff0c;学习一下…...

node.js中express框架cookie-parser包设置cookie的问题

后端使用node.js express cookie-parser技术栈设置cookie的时候出现了无法成功设置的问题 前端发送axios请求部分代码&#xff1a; axios({method: "post",data: {content: remark,relatedArticles: relatedArticleId,userId: userId,userEmail: userEmail,topRema…...

Docker命令手册

大家好&#xff0c;我叫徐锦桐&#xff0c;个人博客地址为www.xujintong.com。平时记录一下学习计算机过程中获取的知识&#xff0c;还有日常折腾的经验&#xff0c;欢迎大家访问。 记录平时用的比较多的Docker命令。 docker学习地址 1、docker停止并删除运行的容器 首先查看…...

Selenium+Pytest自动化测试框架详解

前言 selenium自动化 pytest测试框架 本章你需要 一定的python基础——至少明白类与对象&#xff0c;封装继承&#xff1b;一定的selenium基础——本篇不讲selenium&#xff0c;不会的可以自己去看selenium中文翻译网 一、测试框架简介 测试框架有什么优点 代码复用率高&…...

CentOS7安装部署CDH6.2.1

文章目录 CentOS7安装部署CDH6.2.1一、前言1.简介2.架构3.环境 二、环境准备1.部署服务器2.安装包准备3.修改机器名4.关闭防火墙5.关闭 SELinux6.Hosts文件7.limits文件8.设置swap空间9.关闭透明巨页内存10.免密登录 三、安装CM管理端1.安装第三方依赖包2.安装Oracle的JDK3.安装…...

海思Hi3519DV500边缘计算盒子-英码IVP09A,双核A55 64位处理器

产品简介 IVP09A是英码科技推出的边缘计算智能工作站&#xff0c;搭载双核 Cortex-A55 架构AI 处理器&#xff1b;内置高效的神经网络推理引擎&#xff0c;提供2.5TopsNPU算力;支持多路视频图像识别硬件加速。IVP09A&#xff0c;高效能低成本、稳定易开发、多点布线、联网管控…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...