3、计算瓶颈分析:GPU利用率分析
好,咱们进入正题。GPU集群性能调优,说白了就是跟计算瓶颈死磕。你可能会问,怎么判断瓶颈到底在哪儿?我个人习惯,先看GPU利用率。但注意,这个“利用率”可不是一个简单的百分比数字,它背后藏着好几层信息。
3.1 SM占用率:别被“100%”骗了
很多人一看到GPU利用率100%,就觉得“哇,跑满了,性能没问题”。其实不然。我遇到过好几次,利用率100%,但吞吐量就是上不去。为什么?因为SM(流式多处理器)的占用率,不等于计算单元真的在干活。
SM占用率,指的是SM上活跃的线程束(warp)数量,占最大支持量的比例。这个值高,说明你隐藏了访存延迟,让计算单元尽量不闲着。但如果你kernel里全是访存指令,SM占用率再高,计算单元也在等数据。
- SM活跃率:SM上有指令发射的周期占比。这个才是“真干活”的指标。
- SM占用率:活跃warp数量。高占用率是“隐藏延迟”的前提,但不是性能的保证。
我建议你用 nvidia-smi 看个大概,但真要深挖,得上 Nsight Systems。举个例子,我曾经优化一个矩阵乘的kernel,SM占用率从30%提到80%,但性能只涨了10%。后来发现,瓶颈在L2缓存带宽,SM再多也没用。
3.2 Tensor Core利用率:AI算力的“硬通货”
现在做AI训练,Tensor Core几乎是标配。它的利用率,直接决定了你的训练速度。但Tensor Core不是随便就能用满的。它要求数据布局、精度、维度都满足特定条件。
我记得有一次,团队把FP32的模型改成FP16,以为能直接享受Tensor Core加速。结果一测,Tensor Core利用率不到10%。查了半天,发现是数据排布不对——Tensor Core要求矩阵按行主序连续存储,而我们用了列主序的格式。改完之后,利用率直接飙到80%以上。
nsys profile --stats=true 可以快速看到每个kernel的Tensor Core使用情况。如果发现某个kernel的Tensor Core利用率低,先检查数据精度和布局。
Tensor Core利用率,说白了就是看你的计算指令有没有走到专用的矩阵运算单元上。Nsight Compute里有个指标叫 tensor_core_inst_executed,直接告诉你发了多少条Tensor Core指令。这个值除以总指令数,就是利用率。
3.3 CPU-GPU协同效率:别让一方等另一方
GPU再快,也得靠CPU喂数据。CPU-GPU协同效率,是很多团队容易忽略的瓶颈。你想想看,如果CPU准备数据的速度跟不上GPU计算的速度,那GPU就得空转等着。
我见过一个典型的场景:数据预处理在CPU上做,然后通过PCIe拷贝到GPU。CPU处理一个batch要50ms,GPU计算只要10ms。结果GPU利用率只有20%,因为大部分时间在等数据。解决方案很简单——把数据预处理也搬到GPU上,或者用异步流(stream)让CPU和GPU并行工作。
| 指标 | 说明 | 理想值 |
|---|---|---|
| CPU利用率 | 数据准备线程的CPU占用率 | 接近100%(说明CPU在全力干活) |
| GPU空闲时间 | GPU等待数据的周期占比 | <10% |
| PCIe带宽利用率 | 数据传输占理论带宽的比例 | >70% |
cudaMemcpy 同步拷贝,结果GPU利用率一直上不去。后来改成 cudaMemcpyAsync 配合流,才把CPU和GPU的流水线搭起来。记住,同步拷贝是性能杀手。
3.4 算子性能剖析:Nsight Systems & Nsight Compute
工具是工程师的眼睛。我个人最常用的两把刀:Nsight Systems 看宏观,Nsight Compute 看微观。
3.4.1 Nsight Systems:先看全局
Nsight Systems 能告诉你整个应用的时序图。CPU在干什么,GPU在干什么,数据传输在什么时候发生,一目了然。我习惯先跑一次 nsys profile,看看有没有明显的“空闲气泡”。
# 基本用法
nsys profile -o output_file -t cuda,nvtx ./your_app
# 只看GPU kernel
nsys profile --stats=true -t cuda ./your_app
输出里有个 GPU Utilization 的饼图,会告诉你计算、拷贝、空闲各占多少比例。如果空闲占比超过20%,那肯定有协同问题。
3.4.2 Nsight Compute:深入算子内部
Nsight Compute 是微观分析器。它能告诉你每个kernel的SM效率、内存带宽、指令混合等细节。我遇到性能问题时,会针对最耗时的几个kernel,用 ncu 做逐行分析。
# 分析单个kernel
ncu --kernel-name "matmul_kernel" --set full -o kernel_report ./your_app
输出里有个 Speed of Light 图,直接告诉你这个kernel离理论极限还有多远。如果计算吞吐远低于理论值,那可能是访存瓶颈;如果访存带宽用满了但计算没满,那就是计算瓶颈。
- 用 Nsight Systems 找出最耗时的几个kernel。
- 用 Nsight Compute 逐个分析,看瓶颈在计算还是访存。
- 根据瓶颈类型,针对性优化(比如改数据布局、调block大小、用Tensor Core)。
3.5 知识体系总览
下面这张图,是我自己总结的计算瓶颈分析框架。你可以把它当作一个检查清单,每次遇到性能问题,按这个思路走一遍。
嗯,这张图基本把计算瓶颈分析的脉络理清了。从上到下,先看GPU利用率,再拆到三个子维度,每个维度有关键指标,最后用工具落地。你以后做性能分析,就按这个框架走,不会漏掉关键点。
想要更多资料,联系可可