3. 基准测试工具
做GPU性能调优,手里没几把趁手的工具可不行。我经常跟团队里的小伙伴说,工具就像医生的听诊器——你得知道什么时候用哪个,更要能看懂它告诉你的信息。这一章,我就把压箱底的四件套拿出来,挨个给你讲讲。
1. nvidia-smi:GPU的“体检报告”
这玩意儿,说白了就是NVIDIA自带的监控工具。你装好驱动就有,不用额外折腾。我个人习惯,一上服务器第一件事就是敲nvidia-smi,看看卡的状态。
核心用途:实时监控GPU利用率、显存占用、温度、功耗
先看个最基础的用法:
# 查看所有GPU状态
nvidia-smi
# 每1秒刷新一次
nvidia-smi -l 1
# 只看某个GPU
nvidia-smi -i 0
输出里你会看到几个关键字段:
| 字段 | 含义 | 我关注的点 |
|---|---|---|
| Volatile GPU-Util | GPU计算单元利用率 | 低于80%说明有瓶颈 |
| Memory-Usage | 显存占用 | 别超过90%,容易OOM |
| Temp | 温度 | 超过85°C就要注意散热了 |
| Power | 当前功耗 | 没跑满TDP说明没喂饱 |
小技巧:用nvidia-smi dmon可以看更细粒度的指标,比如PCIe带宽利用率。我曾经排查一个数据搬运慢的问题,就是靠这个发现PCIe链路只跑在x8上。
2. nvprof:老牌性能分析器
嗯,nvprof在CUDA 10之后被标记为deprecated了,但很多老项目还在用。我建议你至少会看它的输出,因为有些老代码的优化报告还是用它生成的。
# 分析整个程序
nvprof ./my_cuda_app
# 只看kernel执行时间
nvprof --print-gpu-trace ./my_cuda_app
# 导出为nvvp可读的文件
nvprof -o profile.nvprof ./my_cuda_app
输出里最重要的几个指标:
- Duration:kernel执行时间,这是最直接的
- Grid/Block Size:启动配置,我经常发现有人设得不对
- Registers Per Thread:寄存器用量,多了会降低occupancy
- Shared Memory:共享内存使用量,影响block数量
注意:nvprof的profiling overhead比较大,尤其是频繁启动小kernel时。我曾经在一个有上千次kernel调用的程序上跑nvprof,结果执行时间翻了3倍。这时候就该用Nsight Systems了。
3. Nsight Systems:系统级性能全景图
这个工具,我愿称之为“上帝视角”。它能告诉你整个程序的时间都花在哪了——不仅仅是GPU,还有CPU、API调用、数据传输。
命令行用法:
# 采集性能数据
nsys profile -o my_report ./my_cuda_app
# 只关注GPU相关
nsys profile -t cuda,nvtx ./my_cuda_app
# 生成可查看的报告
nsys stats my_report.qdrep
Nsight Systems的Timeline视图,说白了就是一条时间轴。你能看到:
- CPU活动:哪些函数在跑,有没有空转
- GPU活动:kernel执行、内存拷贝
- API调用:cudaMemcpy、cudaLaunchKernel这些
- 数据流:CPU和GPU之间的同步点
我的经验:有一次客户说程序跑得慢,我一看Nsight Systems的timeline,发现CPU在等GPU,GPU又在等CPU——典型的“乒乓效应”。加了个异步流,吞吐直接翻倍。
4. Nsight Compute:核函数微观分析器
这是我最常用的工具,没有之一。如果说Nsight Systems是看全局,那Nsight Compute就是拿放大镜看每个kernel的每一行代码。
# 分析单个kernel
ncu -o kernel_analysis ./my_cuda_app
# 只看关键指标
ncu --set full -o full_report ./my_cuda_app
# 分析特定kernel名字
ncu --kernel-name "myKernel" ./my_cuda_app
Nsight Compute的报告里,我最关注这几个section:
| Section | 看什么 | 优化方向 |
|---|---|---|
| Memory Workload Analysis | 内存带宽利用率 | 是否达到理论带宽的80%以上 |
| Compute Workload Analysis | 计算单元利用率 | 有没有被访存拖后腿 |
| Occupancy | SM上活跃warp比例 | 低于50%说明资源受限 |
| Speed of Light | 与理论极限的对比 | 看是计算受限还是访存受限 |
避坑指南:我曾经优化一个矩阵乘法的kernel,光看occupancy觉得没问题,结果Nsight Compute告诉我L2 cache命中率只有30%。后来改了数据布局,命中率提到85%,性能翻了2倍。所以别只看occupancy,要综合看。
工具选择矩阵
你可能会问:这么多工具,我到底该用哪个?我画了张图,帮你理清思路:
说白了,我的工作流是这样的:
- 先跑nvidia-smi,确认GPU没在偷懒
- 用Nsight Systems看全局,找到瓶颈在哪
- 再用Nsight Compute深挖,定位到具体代码行
- 老项目兼容,偶尔用nvprof看看历史数据
重要提醒:别一上来就开Nsight Compute。我见过有人花半小时分析一个kernel,结果发现程序根本没跑在GPU上——CPU端的数据搬运才是瓶颈。先看全局,再下钻,这是铁律。
好了,这四件套你心里有数了吧?工具是死的,思路是活的。下次遇到性能问题,别急着改代码,先拿这些工具“照一照”,问题往往就自己浮出水面了。
我的习惯:在项目里建一个perf_scripts/目录,把常用的nsys、ncu命令写成脚本。这样每次压测,一键跑完所有分析,省时省力。