第3章:性能分析工具入门

做GPU优化,最怕什么?

怕瞎猜。

我见过太多人,上来就改代码,改完跑一下,快了就觉得自己牛,慢了就挠头。其实啊,没有数据支撑的优化,都是耍流氓。这一章,我就带你入门三款最常用的性能分析工具。说白了,就是给你三把尺子,让你能看清GPU到底在干什么。

3.1 NVIDIA Nsight Systems:宏观视角

Nsight Systems,我习惯叫它「系统级分析器」。它的作用,是帮你从全局看问题。

你想想看,一个程序跑得慢,可能是GPU计算慢,也可能是CPU在等数据,还可能是CPU和GPU之间的同步出了问题。Nsight Systems能把这些时间线都画出来,一目了然。

3.1.1 它能告诉你什么?

  • CPU活动:哪些函数在跑,花了多少时间。
  • GPU活动:Kernel执行、内存拷贝、同步操作。
  • API调用:比如cudaMemcpy、cudaLaunchKernel这些。
  • 时间线重叠:CPU和GPU是不是在并行工作?

我个人习惯,拿到一个程序,第一件事就是用Nsight Systems跑一遍。先看宏观,再定微观。

3.1.2 快速上手

安装好之后,命令行里这样用:

nsys profile -o my_profile ./my_cuda_app

这会生成一个 .nsys-rep 文件。用Nsight Systems GUI打开它,就能看到时间线了。

嗯,这里要注意:第一次跑,别加太多选项。默认的采样频率就够用。加多了反而影响程序行为,这叫「观察者效应」。

我的小技巧: 如果程序跑得很快(比如几毫秒),可以加 -t cuda,nvtx 只追踪CUDA和NVTX事件,减少开销。

3.1.3 实战中看什么?

打开时间线后,我一般先看三件事:

  1. 有没有大段的空白?那说明CPU或GPU在空等。
  2. 内存拷贝是不是太频繁?每次拷贝都意味着数据在PCIe总线上来回跑。
  3. Kernel启动有没有延迟?有时候启动Kernel的开销比Kernel本身还大。

我曾经优化过一个流体模拟程序,Nsight Systems一看,发现CPU在每次迭代后都要等GPU完成,白白浪费了30%的时间。后来改成异步流,性能直接翻倍。

3.2 NVIDIA Nsight Compute:微观解剖

如果说Nsight Systems是望远镜,那Nsight Compute就是显微镜。它专门用来分析单个Kernel的性能瓶颈。

3.2.1 核心指标

Nsight Compute会告诉你一堆数字,但别慌。我重点关注这几个:

指标 含义 理想值
Occupancy 每个SM上活跃的Warp比例 越高越好,但别盲目追求
Memory Throughput 显存带宽利用率 接近硬件峰值
Compute Throughput 计算单元利用率 接近硬件峰值
L1/L2 Cache Hit Rate 缓存命中率 越高越好

说白了,你要判断你的Kernel是计算瓶颈还是访存瓶颈。如果是访存瓶颈,Occupancy再高也没用。

3.2.2 使用方式

命令行启动:

ncu -o my_kernel_profile ./my_cuda_app

这会生成一个 .ncu-rep 文件。用Nsight Compute GUI打开,它会自动分析并给出建议。

注意: Nsight Compute会重放Kernel,所以运行时间会比正常慢很多。别用它测性能,只用来分析瓶颈。

3.2.3 一个真实案例

我记得有一次,一个矩阵乘法的Kernel跑得很慢。Nsight Compute一看,Memory Throughput只有30%,而Compute Throughput接近100%。

这说明什么?说明数据没喂饱计算单元。后来我改成共享内存分块,Memory Throughput提升到80%,整体性能快了3倍。

你看,没有Nsight Compute,我可能还在瞎调Occupancy呢。

3.3 nvidia-smi:命令行监控

这个工具,我几乎天天用。它不需要GUI,SSH连上服务器就能用。

3.3.1 基本用法

直接输入:

nvidia-smi

你会看到:

  • GPU型号、显存大小
  • 当前功耗、温度
  • 显存使用率、GPU利用率
  • 正在运行的进程

嗯,这里有个坑:GPU利用率高不一定代表计算单元忙。它可能只是在做内存拷贝。所以别只看这一个数字。

3.3.2 持续监控

如果你想实时看变化,用这个:

nvidia-smi -l 1

每秒刷新一次。我经常在跑长任务时,开一个终端挂着这个命令,随时观察。

3.3.3 查询详细状态

有时候需要更细的信息,比如显存带宽、PCIe链路速度:

nvidia-smi -q -d MEMORY,UTILIZATION

这会输出详细的显存和利用率信息。

避坑指南: 我曾经发现一块GPU的PCIe链路速度只有Gen2,而不是Gen3。查了半天,原来是插槽没插好。用 nvidia-smi -q -d PCIE 就能看到链路状态。

3.4 三把尺子怎么配合?

我一般的工作流是这样的:

  1. 先用nvidia-smi:看看GPU有没有在干活,显存够不够。
  2. 再用Nsight Systems:看全局时间线,找宏观瓶颈。
  3. 最后用Nsight Compute:针对慢的Kernel,做微观分析。

这三步走下来,90%的性能问题都能定位。剩下的10%,嗯,那就要靠经验和直觉了。

好了,这一章就到这里。工具只是手段,关键是你得知道看什么。下一章,我们会深入Kernel优化,到时候这些工具会派上大用场。