当前位置: 首页 > 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;高效能低成本、稳定易开发、多点布线、联网管控…...

从银行转账到会话管理:用C#时间戳实战防重放攻击与用户超时注销

从银行转账到会话管理&#xff1a;用C#时间戳实战防重放攻击与用户超时注销 在金融级应用开发中&#xff0c;时间戳从来不只是简单的时间表示。当用户A在网银发起一笔转账时&#xff0c;系统如何确认这个请求不是黑客截获后重放的旧数据包&#xff1f;当用户B离开电脑半小时后返…...

【STM32HAL库实战】从零构建外部中断:按键唤醒与事件响应

1. 外部中断基础与STM32应用场景 第一次接触STM32外部中断时&#xff0c;我盯着原理图上的按键发呆了半小时——明明GPIO轮询检测就能实现的功能&#xff0c;为什么非要大费周章配置中断&#xff1f;直到某个深夜调试项目时&#xff0c;才真正体会到中断机制的精妙之处。当时我…...

CSS定位如何实现模态框垂直居中_使用负边距或transform

transform: translate(-50%, -50%) 是最稳的居中方式&#xff0c;配合 position: absolute 或 fixed 及 top: 50%、left: 50%&#xff0c;可无视元素尺寸变化实现精准居中&#xff0c;且兼容滚动与响应式场景。用 transform: translate(-50%, -50%) 是最稳的居中方式绝对定位 …...

C语言goto语句的争议与现代替代方案

1. goto语句的本质与历史争议 goto语句是C语言中最具争议的特性之一。从语法上看&#xff0c;它简单到令人不安——只需一个标签和一行指令&#xff0c;就能让程序执行流发生任意跳转。在早期的编程实践中&#xff0c;这种不受约束的控制流方式确实带来了灵活性&#xff0c;但也…...

语雀文档本地化备份工具:轻量级工具实现全流程管理

语雀文档本地化备份工具&#xff1a;轻量级工具实现全流程管理 【免费下载链接】yuque-exporter export yuque to local markdown 项目地址: https://gitcode.com/gh_mirrors/yuq/yuque-exporter 在语雀平台调整服务策略的背景下&#xff0c;如何安全高效地迁移个人创作…...

Spring - 循环依赖

一、循环依赖概览1.1 什么是循环依赖&#xff1f;循环依赖是指两个或多个 Bean 之间互相持有对方引用&#xff0c;形成闭环。例如 A 依赖 B&#xff0c;B 又依赖 A。A 依赖 BB 依赖 A1.2 循环依赖的三种类型// 类型1&#xff1a;构造器注入的循环依赖&#xff08;无法解决&…...

网络资源捕获神器:res-downloader全方位应用指南

网络资源捕获神器&#xff1a;res-downloader全方位应用指南 【免费下载链接】res-downloader 视频号、小程序、抖音、快手、小红书、直播流、m3u8、酷狗、QQ音乐等常见网络资源下载! 项目地址: https://gitcode.com/GitHub_Trending/re/res-downloader 在数字内容日益丰…...

Dockerfile从零入门:手把手教你打包Node.js应用,解决镜像构建的常见坑

代码写完了&#xff0c;在本地跑得好好的&#xff0c;怎么把它打包成Docker镜像&#xff0c;部署到服务器上&#xff1f;答案就是Dockerfile。今天这篇文章&#xff0c;我们用Node.js应用做例子&#xff0c;从零开始写一个Dockerfile&#xff0c;把应用打包成镜像&#xff0c;顺…...

基于NodeJS与CODESYS的OPC UA通信实战:从零搭建工业数据桥梁

1. 为什么需要NodeJS与CODESYS的OPC UA通信&#xff1f; 在工业自动化领域&#xff0c;PLC&#xff08;可编程逻辑控制器&#xff09;就像工厂的"大脑"&#xff0c;负责控制各种设备运行。而CODESYS则是开发PLC程序的"瑞士军刀"&#xff0c;几乎支持所有主…...

IA-Lab AI 检测报告生成助手:双碳目标驱动下的检测机构效率引擎,重塑报告生成与合规审核新模式

在“双碳”目标持续推进的时代背景下&#xff0c;绿色发展已从政策导向转变为企业与机构必须面对的现实命题。对于检测认证&#xff08;TIC&#xff09;行业而言&#xff0c;这一变化尤为明显——碳排放核算、能源效率评估、环境数据监测等业务需求快速增长&#xff0c;检测报告…...