4. 算子性能分析工具
学会用 msprof、msadvisor 这些工具,你就能像医生做CT一样,一眼看穿算子的性能瓶颈。我个人习惯,拿到一个跑得慢的算子,第一件事不是猜,而是直接上 profiler 看数据。你想想看,没有数据支撑的优化,跟蒙着眼睛走路有什么区别?
4.1 msprof:你的第一把手术刀
msprof 是昇腾平台最基础的性能采集工具。说白了,它能把算子执行时的每一段耗时、每一个流水线阶段都记录下来。我在项目中遇到过好几次,明明觉得算子已经很快了,结果 msprof 一跑,发现搬运数据的时间比计算还长。
# 采集整个模型推理的profiling数据
msprof --application="python3 infer.py" --output=./prof_data
# 只采集指定算子的性能(按名称过滤)
msprof --application="python3 infer.py" --op=conv2d --output=./prof_conv
采集完成后,你会得到一个 PROF_XXX 目录。里面包含算子耗时、AI Core 利用率、流水线气泡等等。我个人习惯先看 op_summary.csv,它把每个算子的耗时、输入输出 shape 都列得清清楚楚。
4.2 msadvisor:自动诊断,少走弯路
msadvisor 是 msprof 的好搭档。它基于采集到的数据,自动给出优化建议。嗯,这里要注意:msadvisor 不是万能的,但它能帮你快速缩小排查范围。
# 运行msadvisor分析profiling数据
msadvisor --profiling_dir=./prof_data/PROF_XXX --output=./advice_report
它会生成一份 HTML 报告,里面用红黄绿标注了性能风险。我一般先看红色项,比如“AI Core 空闲率过高”或者“L1 Buffer 命中率低”。
4.3 核心指标:到底该看什么?
很多新手拿到 profiling 数据会懵,一堆数字不知道从哪下手。我教你一个套路:
- 算子耗时占比 —— 找出最耗时的前5个算子,这就是你的头号目标。
- AI Core 利用率 —— 如果低于 60%,说明计算没喂饱,可能是搬运瓶颈或者切分不合理。
- 流水线气泡 —— 看 vector 和 cube 单元是否在空转。我见过一个算子,vector 等数据等了 40% 的时间。
4.4 实战:用 msprof 定位一个慢算子
假设你发现模型推理变慢了。先跑一次 msprof:
msprof --application="python3 -c 'import model; model.infer()'" --output=./prof
打开 op_summary.csv,按耗时降序排列。你可能会看到类似这样的表格:
| 算子名称 | 耗时(us) | AI Core 占比 | 搬运占比 |
|---|---|---|---|
| Conv2D_1 | 1250 | 45% | 55% |
| MatMul_3 | 980 | 70% | 30% |
| Reshape_2 | 120 | 5% | 95% |
看到 Conv2D_1 搬运占比 55%,说明数据搬运拖了后腿。这时候我会用 msadvisor 进一步分析,它可能会建议“使用 double buffer 隐藏搬运延迟”或者“调整分块大小”。
msprof --dvpp 可以单独看 DMA 事件。
4.5 进阶:自定义 profiling 事件
有时候内置的指标不够用,你可以在算子代码里手动插入事件标记。比如在 TIK 算子中:
# 在算子开始和结束处打点
msprof::profiler::start("my_op");
// 算子计算逻辑
msprof::profiler::stop("my_op");
这样在 profiling 结果里就能看到自定义区间的耗时。我经常用这招来测量某个循环或者某个数据预处理阶段的性能。
4.6 总结一下工具链的使用节奏
先 msprof 采集,再用 msadvisor 分析,最后结合 op_summary 和流水线视图定位根因。你想想看,这套流程走下来,大部分性能问题都能水落石出。当然,工具只是辅助,真正的优化还需要你对昇腾架构的理解。下一章我们会聊算子融合策略,到时候你会看到 profiling 数据如何指导融合决策。