4、基准测试工具链:使用perf、nvidia-smi、powerstat等工具进行基础性能采集
说到端侧AI视觉识别的性能测试,我个人的习惯是:先搭好工具链,再谈优化。你想想看,没有数据支撑,你拿什么去说服产品经理改方案?拿什么去跟算法团队battle?
这一章,我们就来聊聊三款最常用的基准测试工具——perf、nvidia-smi、powerstat。它们分别对应CPU、GPU和功耗三大维度。说白了,就是帮你把设备的「体力活」量化出来。
4.1 perf:CPU性能分析的瑞士军刀
perf是Linux内核自带的性能分析工具。我刚开始接触它的时候,觉得这玩意儿参数太多,看着就头大。但用顺手之后,你会发现它真的离不开。
它的核心能力是:统计CPU周期、缓存命中率、分支预测错误、上下文切换等硬件事件。对于视觉识别任务来说,CPU通常负责图像预处理(缩放、归一化)和后处理(NMS、坐标映射)。这些环节一旦出现瓶颈,perf能帮你精准定位。
核心命令速查
perf stat:统计整体性能计数器perf record+perf report:采样并生成热点报告perf top:实时查看CPU热点函数
举个例子,假设我们要测试一个YOLOv5s的预处理流程。我会这样跑:
# 统计预处理函数的CPU性能
perf stat -e cycles,instructions,cache-misses,branch-misses \
./preprocess --input test.jpg --output tensor.bin
输出大概长这样:
Performance counter stats for './preprocess --input test.jpg --output tensor.bin':
1,234,567,890 cycles # 2.4 GHz
2,345,678,901 instructions # 1.9 insn per cycle
12,345 cache-misses # 3.2% of all cache refs
5,678 branch-misses # 1.1% of all branches
0.512345678 seconds time elapsed
这里有个关键指标:instructions per cycle (IPC)。IPC越高,说明CPU流水线越顺畅。如果IPC低于1.0,那就要小心了——大概率是内存访问或者分支预测出了问题。
我的经验
我在项目中遇到过一个问题:同样的预处理代码,在x86上跑得飞快,换到ARM上就慢了一倍。用perf stat一查,发现ARM上的cache-misses高达15%。后来把图像数据从BGR转成RGB的循环改成NEON指令集实现,cache-misses直接降到3%。perf就是这么用的——先看数据,再动手。
4.2 nvidia-smi:GPU状态监控的标配
做端侧AI视觉,GPU(或者NPU)是主力。nvidia-smi是NVIDIA官方提供的GPU监控工具。虽然它主要面向桌面和服务器,但Jetson系列(如Jetson Orin、Xavier)也完全支持。
它的核心输出包括:
- GPU利用率:核心计算单元的繁忙程度
- 显存占用:模型和中间张量占了多少显存
- 温度与功耗:散热和能效的直接体现
- PCIe带宽:数据从CPU到GPU的传输速度
我常用的命令是:
# 每0.5秒刷新一次,显示所有GPU信息
nvidia-smi -l 0.5
# 只显示关键字段,方便脚本解析
nvidia-smi --query-gpu=utilization.gpu,memory.used,temperature.gpu,power.draw \
--format=csv -l 1
输出示例:
utilization.gpu [%], memory.used [MiB], temperature.gpu [°C], power.draw [W]
85 %, 2345 MiB, 72 °C, 12.5 W
92 %, 2345 MiB, 74 °C, 13.2 W
88 %, 2345 MiB, 73 °C, 12.8 W
这里要注意:GPU利用率不等于性能。利用率高可能只是说明任务调度密集,但不代表吞吐量高。我见过有人把GPU跑到99%,但FPS只有15——后来发现是模型太小,频繁启动kernel的开销占了大部分时间。
避坑指南
我曾经在Jetson Orin上测试一个轻量级模型,nvidia-smi显示GPU利用率只有30%。我以为模型没跑满,就拼命调大batch size。结果利用率上去了,但延迟也翻倍了。后来用perf一看,发现瓶颈在CPU的DMA传输上。所以记住:nvidia-smi只看GPU,不代表整个系统。要结合perf一起看。
4.3 powerstat:功耗测量的实用工具
端侧设备最敏感的是什么?功耗。尤其是做视觉识别的产品,摄像头一直开着,模型一直跑着,功耗稍微高一点,电池就扛不住。
powerstat是Ubuntu上常用的功耗测量工具。它通过读取ACPI或RAPL接口,统计系统的实时功耗。用法非常简单:
# 每1秒采样一次,共采样60次
sudo powerstat 1 60
输出示例:
Time User Nice Sys Idle IO Run Ctxt/s IRQ/s Watts
10:00:01 8.2 0.0 2.1 89.7 0.0 1 1234 567 5.2
10:00:02 45.3 0.0 12.4 42.3 0.0 2 5678 1234 12.8
10:00:03 48.1 0.0 11.9 40.0 0.0 2 6123 1345 13.1
...
Average: 35.2 0.0 9.8 55.0 0.0 1.5 4567 1023 10.5
关键字段:
- Watts:当前系统总功耗(包括CPU、GPU、内存、外设)
- User/Sys/Idle:CPU时间分布,帮你判断功耗是花在用户态还是内核态
- Ctxt/s:上下文切换次数,过高说明调度有问题
我的用法
我一般会跑三组数据:
- 空闲功耗:系统待机,什么都不跑
- 满载功耗:跑一个高负载的视觉模型(比如YOLOv8m)
- 目标功耗:跑我们实际要部署的模型
然后算一个「增量功耗」:目标功耗 - 空闲功耗。这个值才是模型本身带来的功耗开销。我曾经用这个方法发现,某个模型的预处理环节占了总功耗的30%——后来把图像缩放的算法从双线性改成最近邻,功耗直接降了15%。
4.4 三件套组合拳:一个完整的采集脚本
在实际项目中,我不会一个一个工具单独跑。那样太慢了,而且时间戳对不上。我习惯写一个脚本,同时采集CPU、GPU、功耗数据。
下面是我常用的模板:
#!/bin/bash
# 端侧AI视觉识别性能采集脚本
# 用法:./collect_perf.sh <模型可执行文件> <输入图像>
MODEL=$1
INPUT=$2
OUTPUT_DIR="perf_results_$(date +%Y%m%d_%H%M%S)"
mkdir -p $OUTPUT_DIR
# 1. 启动功耗采集(后台运行)
sudo powerstat 0.5 120 > $OUTPUT_DIR/power.log &
POWER_PID=$!
# 2. 启动GPU监控(后台运行)
nvidia-smi --query-gpu=utilization.gpu,memory.used,temperature.gpu,power.draw \
--format=csv -l 0.5 > $OUTPUT_DIR/gpu.log &
GPU_PID=$!
# 3. 运行CPU性能分析
perf stat -e cycles,instructions,cache-misses,branch-misses \
-o $OUTPUT_DIR/perf_stat.log \
$MODEL $INPUT
# 4. 停止后台进程
kill $POWER_PID $GPU_PID 2>/dev/null
echo "采集完成,结果保存在 $OUTPUT_DIR"
跑完之后,你会得到三个文件:
perf_stat.log:CPU性能计数器gpu.log:GPU利用率、显存、温度、功耗时间序列power.log:系统总功耗时间序列
然后你就可以对着这些数据,开始做性能分析了。比如:
- CPU的cache-misses是不是太高?
- GPU利用率有没有波动?
- 功耗曲线有没有异常尖峰?
核心要点总结
- perf:看CPU内部事件,定位代码级瓶颈
- nvidia-smi:看GPU状态,确认计算资源是否用满
- powerstat:看系统功耗,评估能效比
- 组合使用:同时采集,时间对齐,才能做系统级分析
嗯,工具链就这些。下一章我们会聊怎么用这些数据,来指导具体的性能优化。到时候你会发现,数据采集只是第一步,怎么解读数据才是真正的功夫。