性能工程:测量、Roofline、瓶颈定位与优化闭环 / Performance Engineering with Measurement, Roofline, and Bottleneck Analysis
📅 创建时间:2026-07-20 🏷️ 标签:#性能分析 #Roofline #Profiling #Benchmark 📚 前置知识:[[09-distributed-parallelism]] 📚 相关知识:[[/02-systems-and-performance/02-computer-architecture-and-hardware/11-performance-analysis-tools]] [[/02-systems-and-performance/02-computer-architecture-and-hardware/06-cuda-optimization]]
1. 优化的第一原则
不要优化你认为最慢的地方,要优化测量证明最慢且值得优化的地方。
完整闭环:
建立基线 → 定位热点 → 提出假设 → 单点修改 → 重新测量 → 检查正确性一次只改变关键变量,否则无法确定收益来源。
2. 先定义目标
性能可能指不同指标:
- 单次请求延迟
- 稳态吞吐
- P95/P99 尾延迟
- 每瓦性能
- 单位成本吞吐
- 最大可处理规模
- 强扩展或弱扩展效率
优化平均吞吐可能恶化尾延迟,减少时间也可能增加内存占用。目标必须与应用需求一致。
3. 建立可信基线
基准测试至少要控制:
- 输入数据与问题规模
- 编译优化等级
- 预热和首次初始化
- CPU 频率、线程绑定和后台负载
- GPU 型号、驱动和功耗状态
- 多次运行的波动
- 是否包含 I/O 和数据传输
报告结果时同时记录硬件、软件版本和测试命令。
4. Roofline 模型
Roofline 用算术强度判断程序受计算还是带宽限制:
可达到性能 ≤ min(计算峰值, 内存带宽 × 算术强度)性能
│ ───────── 计算峰值
│ __/
│ __/
│ __/ 带宽限制区
└──────────────────────── 算术强度受带宽限制
优化方向:减少数据移动、改善局部性、合并访问、提高数据复用。
受计算限制
优化方向:使用 SIMD/Tensor Core、减少无效运算、提高指令吞吐、选择合适精度。
5. CPU 分析指标
常见关注点:
- CPU 利用率和每核负载
- IPC:每周期执行指令数
- 分支预测失败
- L1/L2/L3 Cache Miss
- 内存带宽
- 上下文切换与锁等待
- NUMA 远程访问
常用工具包括 perf、VTune、Linux time、火焰图和编译器向量化报告。
6. GPU 分析指标
常见关注点:
- Kernel 执行时间
- SM 活跃度和 Occupancy
- Warp Stall 原因
- Global Memory 吞吐
- 合并访存效率
- 分支发散
- Tensor Core 利用率
- Host-Device 拷贝与同步
工具包括 Nsight Systems 和 Nsight Compute:前者观察端到端时间线,后者深入单个 Kernel 指标。
7. 集群分析指标
- 各 Rank 计算时间分布
- 集合通信耗时
- 网络吞吐和拥塞
- GPU 间拓扑路径
- Barrier 等待时间
- 数据加载和 Checkpoint 时间
- 慢节点与性能抖动
只看平均值可能掩盖 Straggler,应关注最慢 Rank 和长尾分布。
8. 常见优化误区
- 只看 CPU/GPU 利用率百分比
- 只优化微型 Kernel,忽略端到端流程
- 追求最高 Occupancy
- 用更多线程掩盖负载不均
- 没有验证结果数值正确性
- 在 Debug 构建上比较性能
- 忽略首次 JIT、缓存和预热
- 用峰值 FLOPS 直接估算真实程序
9. 优化优先级
通常按以下顺序更稳妥:
- 修正算法复杂度和不必要工作。
- 减少数据规模、拷贝和格式转换。
- 改善数据布局与局部性。
- 提高任务粒度和负载均衡。
- 并行化主要热点。
- 重叠计算与通信。
- 最后进行指令级和 Kernel 微调。
算法从 O(n²) 降到 O(n log n),通常比手写汇编更有价值。
历史性能工程补充
本页保留课程合并前的性能工程说明。
当前版本增加基线、扩展、工具、回归和报告验收。
串行基线
基线必须正确、合理优化且可复现。
不能用低质量基线夸大并行收益。
强扩展
固定问题规模,增加资源。
记录加速比、效率、通信和最慢任务。
弱扩展
每资源工作量近似固定。
观察全局同步、I/O 和内存增长。
阶段
分解初始化、计算、通信、同步、I/O 和结束。
优化后重新查看瓶颈迁移。
不均衡
比较每线程、Rank 和 GPU。
最大时间决定同步尾部。
同步
记录锁、Barrier、原子、Collective 和 Event。
必要同步与伪依赖需要区分。
通信
小消息偏延迟,大消息偏带宽。
拓扑、拥塞和拷贝进入真实成本。
Roofline
算术强度连接操作和字节。
模型用于选择实验,不替代测量。
CPU 工具
- WPR/WPA;
- VTune Hotspots;
- VTune Threading;
- VTune Memory Access;
- Perf。
GPU 工具
- Nsight Systems;
- Nsight Compute;
- 框架 Profiler。
先系统时间线,再单 Kernel。
MPI 工具
记录消息、Collective、等待、映射和 Straggler。
正确性
- 结果;
- 容差;
- 数据竞争;
- 内存安全;
- 取消;
- Checkpoint;
- 资源释放。
资源
记录内存、显存、网络、磁盘、能耗和成本。
实验
一次改变一个主要因素。
交错 A/B,保存原始样本。
回归
小基准进入 PR。
大规模基准进入专用 Runner。
基线变更需要审批。
历史结果边界
旧硬件、工具和运行库的性能不能直接外推。
引用时保留环境、输入、命令和正确性。
当前课程映射
当前文章补充:
- 强弱扩展;
- 阶段分解;
- CPU/GPU/MPI 工具;
- 正确性与资源;
- 回归;
- 报告验收。
阅读完成标准
应能:
- 建立基线;
- 分解时间;
- 找不均衡;
- 分析通信;
- 使用 Profile;
- 验证正确性;
- 建立回归;
- 限定历史数字。
归档实验清单
复现历史优化时记录:
- 来源提交;
- 算法版本;
- 编译器;
- 优化选项;
- CPU/GPU;
- 内存与 NUMA;
- 驱动;
- MPI/线程库;
- 输入与校验和;
- 线程数;
- Rank/节点;
- GPU 数;
- 进程映射;
- 预热;
- 样本;
- 原始 Profile;
- 阶段时间;
- 通信;
- 峰值内存;
- 正确性;
- 当前结果差异。
无法复原原环境时,报告替代平台和可能影响。
归档结论规则
历史优化结论只能说明原工作负载中的观测。
新平台必须重新建立基线和 Profile。
指标名称相同也可能来自不同事件或工具版本。
性能数字不与正确性分离。
失败实验应保留,以免重复尝试。
当前课程中的方法优先,历史正文用于补充原始上下文。 所有复现命令应进入报告附件。
性能实验记录模板
目标:
硬件与软件环境:
输入规模:
基线结果:
热点证据:
优化假设:
修改内容:
优化后结果:
正确性检查:
结论与下一步:下一篇:[[11-application-cases]]