Skip to content
Gains Summary
Main Navigation 首页 / Home
C++ 编程 / C++ Programming
系统与高性能 / Systems & Performance
Web 开发 / Web Development
人工智能 / Artificial Intelligence
工业软件 / Industrial Software
其他内容 / Other Topics
C++ 编程 / C++系统与性能 / SystemsWeb 开发 / Web人工智能 / AI工业软件 / Industrial

外观

Sidebar Navigation

← 系统与高性能 / Systems & Performance

计算系统 / Computing Systems

1. 计算系统:计算机如何执行与加速程序

2. 从 C++ 源码到 CPU 执行

3. CPU 流水线、乱序执行与分支预测

4. Cache、一致性、伪共享与 NUMA

5. GPU、SM、Warp 与显存

6. 计算执行模型:程序怎样映射到机器

7. SIMD 与编译器向量化

8. C++ 多线程与 OpenMP

9. CUDA 平台与编程模型

10. CUDA Kernel、内存与性能

11. CPU-GPU 异构流水线

12. MPI 与分布式并行

13. 并行算法模式

14. 性能模型与工具

15. 递进学习项目:从单线程到集群

历史完整正文 / Original Deep Dives

1. 历史完整正文:统一前文章逐篇保留

原体系结构与硬件 / Original Architecture

1. 硬件编程与高性能计算:一张可走通的学习地图 / A Practical Learning Map for Hardware Programming and HPC

2. 计算机体系结构:CPU、内存与 GPU / Computer Architecture: CPUs, Memory, and GPUs

3. 计算机架构基础——为什么 GPU 比 CPU 更快 / Computer Architecture Fundamentals: Why GPUs Outperform CPUs

4. 并行计算理论——30 天训练能优化到多快? / Parallel Computing Theory and the Limits of Training Acceleration

5. GPU 架构深入——上万个核心如何分工协作 / GPU Architecture and Massive Parallel Execution

6. CUDA 编程模型——把矩阵乘法映射到 GPU / The CUDA Programming Model for Mapping Matrix Multiplication to GPUs

7. CUDA 内存管理——百亿参数如何装进显存 / CUDA Memory Management for Large Models

8. CUDA 性能优化——从 30 天缩短到 10 天 / CUDA Performance Optimization

9. CPU 并行编程——OpenMP 与 SIMD 向量化 / CPU Parallel Programming with OpenMP and SIMD

10. HPC 集群与 MPI——多节点分布式训练 / HPC Clusters and MPI for Distributed Training

11. 异构计算——CPU 与 GPU 如何协同工作 / Heterogeneous Computing with CPUs and GPUs

12. 深度学习训练优化实战——从 30 天到 3 天 / Deep Learning Training Optimization from Thirty Days to Three

13. 性能分析工具——找到真正的瓶颈 / Performance Analysis Tools for Finding Real Bottlenecks

14. NPU 全景——昇腾/寒武纪/TPU/苹果生态 / The NPU Landscape: Ascend, Cambricon, TPU, and Apple

15. 未来趋势——2030 年的计算机会是什么形态 / Future Computing Trends Toward 2030

16. 硬件与高性能计算:从“程序为什么慢”开始 / Hardware and HPC Starting from Why Programs Are Slow

原并行计算 / Original Parallel Computing

1. 并行计算:从 SIMD 到 MPI / Parallel Computing from SIMD to MPI

2. 并行计算全景:从晶体管、CPU、GPU 到计算集群 / Parallel Computing from Transistors, CPUs, and GPUs to Clusters

3. 并行计算基础:任务分解、加速比与可扩展性 / Parallel Computing Fundamentals: Decomposition, Speedup, and Scalability

4. 处理器体系结构:从指令流水线到多核芯片 / Processor Architecture from Instruction Pipelines to Multicore Chips

5. CPU 并行:多线程、SIMD、Cache 一致性与 NUMA / CPU Parallelism with Threads, SIMD, Cache Coherence, and NUMA

6. 内存层次:Cache、带宽、局部性与一致性 / Memory Hierarchies, Bandwidth, Locality, and Coherence

7. GPU 体系结构:SIMT、Warp、SM 与吞吐优先设计 / GPU Architecture with SIMT, Warps, and Streaming Multiprocessors

8. CUDA 编程模型:Thread、Block、Grid 与内存协作 / CUDA Threads, Blocks, Grids, and Cooperative Memory Access

9. 并行算法模式:Map、Reduce、Scan、Stencil 与任务图 / Parallel Patterns: Map, Reduce, Scan, Stencil, and Task Graphs

10. 异构计算:CPU、GPU、NPU 如何协同工作 / Heterogeneous Computing with CPUs, GPUs, and NPUs

11. 分布式并行:MPI、集合通信、RDMA 与多机多卡 / Distributed Parallelism with MPI, Collective Communication, and RDMA

12. 性能工程:测量、Roofline、瓶颈定位与优化闭环 / Performance Engineering with Measurement, Roofline, and Bottleneck Analysis

13. 并行计算实战:AI、CAE、图像与科学计算 / Parallel Computing for AI, CAE, Imaging, and Scientific Computing

14. 并行计算实践路线:从单核优化到多机多卡 / A Parallel Computing Project Path from Single-Core to Multi-Node GPUs

本页目录

性能分析工具——找到真正的瓶颈 / Performance Analysis Tools for Finding Real Bottlenecks ​

📅 创建时间:2026-06-02 🏷️ 标签:#HPC #性能分析 #nsys #ncu #vtune #PyTorchProfiler 📚 前置知识:[[06-cuda-optimization]](CUDA 优化) [[10-dl-training-optimization]](训练优化) 📚 相关知识:[[05-cuda-kernel-and-memory]](内存管理)


先抓住直觉 ​

Profiler 像医院检查:先判断问题发生在整条训练流水线、某个 Kernel,还是内存分配,再选择对应工具。指标不是分数;“越高越好”通常不成立,关键是它能否解释实际耗时。

  • 必须理解:先建立基线;从总时间逐层下钻;一次只验证一个假设。
  • 用到再查:nsys、ncu 和 PyTorch Profiler 的命令参数。
  • 最小流程:复现 → 测量 → 定位最大耗时 → 提出假设 → 修改 → 用同一基线复测。

场景:优化了半天,为什么还是没快? ​

┌─────────────────────────────────────────────────────────────┐
│                                                             │
│  你做了一堆优化:                                          │
│  ✅ 合并内存访问                                          │
│  ✅ 使用共享内存                                          │
│  ✅ 优化了 block 大小                                     │
│                                                             │
│  自测结果:                                               │
│  优化前:15 GFLOPS                                       │
│  优化后:18 GFLOPS                                       │
│                                                             │
│  提升 20%,但离 A100 的 156 TFLOPS 还差很远!           │
│                                                             │
│  瓶颈到底在哪里?                                         │
│  → 盲目优化 = 浪费时间                                   │
│  → 必须用工具定位瓶颈!                                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

第1节:性能分析工具全景 ​

┌─────────────────────────────────────────────────────────────┐
│                    NVIDIA 性能分析工具                      │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Nsight Systems(nsys):                                  │
│  定位:系统级 timeline 分析                                 │
│  看什么:CPU-GPU 传输时间、kernel 执行顺序、并行度         │
│  类比:航空调度中心,看整个机场的运行                      │
│                                                             │
│  Nsight Compute(ncu):                                   │
│  定位:kernel 级别性能分析                                 │
│  看什么:SM 利用率、内存带宽、warp 效率、瓶颈类型         │
│  类比:单架飞机黑匣子,看具体故障原因                      │
│                                                             │
│  PyTorch Profiler:                                        │
│  定位:深度学习训练性能分析                               │
│  看什么:每层的耗时、CPU-GPU 传输、内存使用               │
│                                                             │
│  VTune(Intel):                                          │
│  定位:CPU 性能分析                                       │
│  看什么:CPU 利用率、OpenMP 效率、SIMD 利用率             │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

第2节:Nsight Systems——系统级 Timeline ​

基本用法 ​

bash
# 抓取性能数据
nsys profile --trace=cuda,nvtx,osrt \
              --output=my_profile \
              ./my_cuda_app

# 生成 .qdrep 文件
# 用 Nsight Systems GUI 打开查看

# 或者命令行快速查看
nsys stats my_profile.qdrep
1
2
3
4
5
6
7
8
9
10

输出解读 ​

┌─────────────────────────────────────────────────────────────┐
│                    nsys timeline 输出示例                      │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  GPU Core:                                               │
│  ┌────────┬────────┬────────┬────────┬────────┐        │
│  │Kernel A│Kernel B│Kernel A│Kernel C│ Idle   │        │
│  └────────┴────────┴────────┴────────┴────────┘        │
│  0ms     5ms     10ms     15ms     20ms     25ms        │
│                                                             │
│  观察:Kernel A 和 B 顺序执行,没有并行!                  │
│  → 可以用 CUDA Stream 并行化                                │
│                                                             │
│  GPU Utilization: 45%                                      │
│  CPU-GPU Memcpy: 30%                                     │
│  GPU Kernel: 45%                                          │
│  Idle: 25%                                                │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

常见问题的 timeline 特征 ​

┌─────────────────────────────────────────────────────────────┐
│                    典型问题识别                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  问题1:CPU-GPU 传输瓶颈                                  │
│  Timeline: [H2D][GPU][D2H][H2D][GPU][D2H]               │
│  解决:用 CUDA Stream 重叠传输和计算                       │
│                                                             │
│  问题2:GPU 空闲等待                                       │
│  Timeline: [GPU-Kernel][CPU-Preprocess][GPU-Kernel]      │
│  解决:Double Buffering,CPU 和 GPU 并行                   │
│                                                             │
│  问题3:kernel 顺序执行                                   │
│  Timeline: [Kernel A][     Kernel B     ]                 │
│  解决:用多个 CUDA Stream 并行                             │
│                                                             │
│  问题4:频繁的小 kernel 调用                              │
│  Timeline: [K1][K2][K3][K4][K5][K6][K7][K8]            │
│  解决:合并多个小 kernel 为一个                            │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

第3节:Nsight Compute——Kernel 级分析 ​

基本用法 ​

bash
# 抓取 kernel 级别数据
ncu --set full \
    --output my_kernel_profile \
    ./my_cuda_app

# 或者针对特定 kernel
ncu --set full \
    --kernel-name "matrix_mul_kernel" \
    --output my_kernel_profile \
    ./my_cuda_app
1
2
3
4
5
6
7
8
9
10

输出指标解读 ​

┌─────────────────────────────────────────────────────────────┐
│                    ncu 输出指标解读                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  SM Utilization:                                           │
│  值:75%                                                  │
│  含义:75% 的时间 SM 在执行有效指令                       │
│  低原因:分支分化、Warp 等待内存、Occupancy 低           │
│                                                             │
│  Memory [GB/s]:                                          │
│  Achieved:1800 GB/s                                       │
│  说明:实际内存带宽使用                                    │
│  对比 HBM2e 理论:2000 GB/s → 利用率 90%               │
│                                                             │
│  SM Active Cycles:                                        │
│  值:high                                                │
│  含义:计算单元利用率高                                    │
│                                                             │
│  L1/TEX Cache Hit Rate:                                  │
│  值:60%                                                  │
│  含义:40% 的内存访问走了全局内存(慢)                  │
│  解决:增加共享内存使用                                    │
│                                                             │
│  Warp Occupancy:                                         │
│  值:48 warps/SM                                          │
│  含义:每 SM 平均 48 个 warp 在调度                       │
│  对比最大 64 warps/SM → Occupancy 75%                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

瓶颈定位流程 ​

┌─────────────────────────────────────────────────────────────┐
│                    ncu 瓶颈定位流程                         │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Step 1: 查看 SM Utilization                              │
│  ├─ 低(< 50%):→ Step 2                                │
│  └─ 高(> 80%):→ Step 3                                │
│                                                             │
│  Step 2: 查看 Warp Execution Efficiency                    │
│  ├─ 低(< 95%):分支分化问题                             │
│  └─ 高(> 95%):→ Occupancy 问题                         │
│                                                             │
│  Step 3: 查看 MemorySOL / ComputeSOL                       │
│  ├─ MemorySOL < 50%:内存带宽瓶颈                        │
│  └─ ComputeSOL < 50%:计算单元瓶颈                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

第4节:PyTorch Profiler——训练性能分析 ​

基本用法 ​

python
import torch
from torch.profiler import profile, ProfilerActivity

with profile(
    activities=[ProfilerActivity.CPU, ProfilerActivity.CUDA],
    record_shapes=True,
    profile_memory=True,
    with_stack=True
) as prof:
    # 训练循环
    for batch in dataloader:
        output = model(batch.input)
        loss = criterion(output, batch.target)
        loss.backward()
        optimizer.step()

# 打印耗时最多的 10 个操作
print(prof.key_averages().table(sort_by="cuda_time_total", row_limit=10))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

输出解读 ​

┌─────────────────────────────────────────────────────────────┐
│                    PyTorch Profiler 输出示例                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Name                                        CUDA Time  %  │
│  ──────────────────────────────────────────────────────────│
│  cudaLaunchKernel                             1000 ms   10%│
│  amp::fastMixedPrecisionKernel                 2500 ms   25%│
│  layernorm_forward                            1200 ms   12%│
│  embedding_forward                            800 ms    8% │
│  tensor_expr_gpu_kernel                       600 ms    6% │
│  aten::matmul                                400 ms    4% │
│  ...                                                         │
│                                                             │
│  观察:amp::fastMixedPrecisionKernel 耗时最长(25%)        │
│  → 可能是 Tensor Core 利用率低                              │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

导出和可视化 ​

python
# 导出 Chrome Trace 格式
prof.export_chrome_trace("trace.json")

# 在 Chrome 浏览器打开:chrome://tracing
# 可以看到每个操作的时间线和调用栈

# 导出内存快照
prof.export_memory_timeline("memory.html", device_index=0)
# 查看显存使用随时间的变化
1
2
3
4
5
6
7
8
9

第5节:实用调试流程 ​

┌─────────────────────────────────────────────────────────────┐
│                    性能调试完整流程                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 系统级:nsys timeline                                 │
│     ├─ CPU-GPU 传输是否重叠?                            │
│     ├─ GPU 是否空闲等待?                                   │
│     └─ kernel 是否并行执行?                               │
│                                                             │
│  2. Kernel 级:ncu profile                                │
│     ├─ SM Utilization 高还是低?                         │
│     ├─ 内存带宽利用率?                                   │
│     └─ Warp 效率?                                        │
│                                                             │
│  3. 热点分析:                                            │
│     ├─ 哪个 kernel 占时间最多?                           │
│     ├─ 哪个操作显存占用最大?                             │
│     └─ 哪层耗时最长?                                     │
│                                                             │
│  4. 针对性优化:                                           │
│     ├─ 内存带宽瓶颈 → 合并访问、共享内存复用              │
│     ├─ Warp 效率低 → 减少分支分化                        │
│     ├─ CPU-GPU 不同步 → Double Buffering                  │
│     └─ Occupancy 低 → 调整 block 大小                     │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

"AI 可查 vs 必须理解"清单 ​

AI 可查:
✅ nsys/ncu 的具体命令行参数
✅ PyTorch Profiler 的具体配置选项
✅ Chrome Trace 格式的解读方法

必须理解:
🔴 nsys = 系统级 timeline,定位 CPU-GPU 协同问题
🔴 ncu = kernel 级分析,定位单 kernel 性能瓶颈
🔴 SM Utilization 低 = warp 调度不足或等待内存
🔴 Memory SOL 低 = 内存带宽瓶颈
🔴 PyTorch Profiler = 训练性能分析,定位哪层最慢
1
2
3
4
5
6
7
8
9
10
11

学习状态:🟡 开始学习


历史版本补充说明 ​

本页保留课程合并前的工具介绍,命令、指标名称和界面可能随工具版本变化。

当前扩展版工具指南位于:

  • 性能分析工具:WPR、WPA、VTune、Nsight 与 PyTorch Profiler

查阅历史内容时请注意:

  • WPR 负责基于 ETW 采集 Windows 系统和应用事件;
  • WPA 负责打开 ETL,分析 CPU、线程状态、I/O、内存和关键路径;
  • VTune 从 Hotspots 进入 Threading、Memory Access 与 Microarchitecture;
  • Nsight Systems 观察 CPU/GPU 时间线;
  • Nsight Compute 下钻 NVIDIA 单个 Kernel;
  • PyTorch Profiler 连接框架 Operator 与 CPU/CUDA 活动。

工具参数以当前安装版本的帮助和官方文档为准。 历史阈值不能机械套到新硬件,指标必须和耗时、工作负载及正确性一起解释。

推荐使用顺序:先用低开销系统级采集找到慢阶段,再对具体 CPU 函数、线程等待或 GPU Kernel 使用深度分析,修改后回到同一端到端基线复测。

WPR 与 WPA 的职责分离 ​

WPR 是采集器,它根据 Profile 启用 ETW Provider、Kernel Event 和 Stack,并把结果写入内存循环缓冲区或 ETL 文件。WPA 是分析器,它打开 ETL 后提供时间线与可透视表格。CPU Usage (Sampled) 用采样栈定位执行热点,CPU Usage (Precise) 使用上下文切换事件区分 Running、Ready 和 Wait,并能沿唤醒关系追踪关键路径。两者配合适合 Windows 应用卡顿、启动、磁盘、内存和后台功耗问题。

WPR 的使用逻辑 ​

采集前先明确现象和时间窗口,再通过 wpr -profiles 查看本机内置 Profile。可控短场景使用文件模式,偶发问题使用内存循环模式并在症状出现后立即停止。只启用回答问题所需的 Provider 和 Stack,防止采集本身产生大量 I/O。ETL 必须与应用构建、PDB 和复现步骤一起保存,否则 WPA 中只能看到地址或无法判断操作区间。

WPA 的使用逻辑 ​

打开 ETL 后先缩放到用户感知的慢区间并过滤目标进程。CPU 很高时看 Sampled Stack,CPU 很低但操作很慢时看 Precise 的线程状态、Readying Thread 与 Wait Reason。文件读取问题同时查看 File I/O 和 Disk Usage,区分页缓存与物理设备。任何表格都应保留时间范围、分组列和聚合口径,避免截图脱离上下文。

VTune 的使用逻辑 ​

VTune 通常从 Hotspots 开始,确认最耗时函数和调用路径。多线程扩展差时进入 Threading,查看并行度、同步等待和负载不均;怀疑 Cache、带宽或 NUMA 时进入 Memory Access;需要解释前端、推测和后端槽位时使用 Microarchitecture Exploration。分析名称和 Knob 随版本变化,命令应通过当前安装的 vtune -help collect 核对。

工具组合 ​

WPA 擅长 Windows 全系统事件与线程因果,VTune 擅长 Intel CPU 应用源码和微架构,Nsight Systems 擅长 CPU/NVIDIA GPU 协同时间线,Nsight Compute 擅长单个 NVIDIA Kernel,PyTorch Profiler 负责框架 Operator 与 CPU/CUDA 活动的对应。没有一个工具可以一次回答全部问题。正确流程是先定位层次,再选择更深的采集。

历史版本边界 ​

本页原始内容以 Nsight 和 PyTorch 为主,当前扩展版已经加入 WPR、WPA 与 VTune 的详细流程。历史截图中的百分比和阈值不能当作所有硬件通用标准,尤其是 SOL、Occupancy、Cache Hit 和 Warp 指标。复现时保存工具版本、采集命令、原始报告、输入和正确性结果,并用同一端到端基线验证优化。

最后更新于:

Pager
上一篇12. 深度学习训练优化实战——从 30 天到 3 天 / Deep Learning Training Optimization from Thirty Days to Three
下一篇14. NPU 全景——昇腾/寒武纪/TPU/苹果生态 / The NPU Landscape: Ascend, Cambricon, TPU, and Apple

持续记录,持续成长

Copyright © Tidenflow