Appearance
Profiling
状态:入门理解 · 更新于 2026-09-14
Profiling 要回答的是“时间花在哪里、为什么花在那里、改动是否真的有效”。先用时间线定位范围,再对单个 Kernel 做硬件计数器分析,最后回到端到端回归。
工具分工
| 工具 | 观察范围 | 适合回答的问题 |
|---|---|---|
| Nsight Systems | 进程、线程、CUDA API、Kernel、Memcpy、NCCL 时间线 | CPU/GPU 是否重叠?哪里在等待?调用间隙多不多? |
| Nsight Compute | 单个 CUDA Kernel 的指标和源码关联 | 带宽、计算吞吐、Occupancy、分支和缓存问题在哪里? |
| PyTorch Profiler | 框架 Operator、Autograd、CUDA 活动 | 哪个框架算子触发了热点?算子与 Kernel 如何对应? |
| NCCL Tests | 多卡集合通信 | 通信带宽和拓扑是否达到基线? |
不要一开始就打开所有高开销指标。先缩短复现样本,再逐步增加采集范围。
推荐工作流
1. 固定可复现样本
固定硬件、软件、输入 shape、Batch、dtype、线程数和随机种子。先预热,排除首次编译、内存分配和缓存建立的影响;记录中位数、P95 与方差。
2. 用时间线找大块时间
例如:
bash
nsys profile --trace=cuda,nvtx,osrt -o timeline python train_or_infer.py重点看 Kernel 之间的空洞、H2D/D2H 拷贝、同步调用、CPU 调度和 NCCL 通信。若端到端瓶颈在等待或通信,继续优化某个 Kernel 的指令效率可能没有收益。
3. 钻取目标 Kernel
bash
ncu --set full -o kernel_report ./kernel_app先关注该 Kernel 的时间占比、Global/Shared Memory 访问、计算吞吐、Occupancy、寄存器和分支效率,再根据问题选择更窄的 section。不同 GPU 架构的指标名称和可用性会变化,不要把某一代卡的阈值硬套到另一代。
4. 建立证据链
每次改动都保留:提交版本、运行参数、Profile 文件、基线结果、优化结果和误差检查。性能提升只有在相同环境、相同样本和重复测量中稳定出现,才算有效。
指标如何解释
- SM/计算吞吐低:可能是并行度不足、访存等待、分支分化或依赖链过长;不能只凭一个利用率数字下结论。
- 显存带宽高:可能是合理的流式访问,也可能是在反复搬运中间张量;要结合字节数和算法需求。
- Occupancy 低:先检查寄存器、Shared Memory 和 Block 配置,再判断是否真的限制吞吐。
- Kernel 很短但端到端很慢:优先检查 Launch 间隙、同步、分配、数据转换和通信。
- 时间抖动大:排查频率、温度、后台任务、首次编译和动态 shape。
结果验证
性能 Profile 不能替代正确性测试。至少覆盖:随机输入、全零/极值、非整齐 shape、不同 dtype 和长序列;对浮点结果使用与算法相符的绝对/相对误差标准。量化和近似算法还要记录精度指标,而不是只比较逐元素误差。
信息来源
延伸阅读
更新日志
- 2026-09-14:建立时间线、Kernel 指标和回归验证的 Profiling 方法。