硬件与高性能计算:从“程序为什么慢”开始 / Hardware and HPC Starting from Why Programs Are Slow
这套笔记不是硬件名词词典。它只围绕一个问题展开:
一段程序为什么慢,我们能从哪里把时间省下来?
先别急着记 CUDA Core、Warp、HBM 和 NCCL。面对任何性能问题,先问下面四句话:
- 算得慢吗? 算术单元来不及完成工作。
- 取得慢吗? 数据没有及时送到计算单元。
- 等得久吗? CPU、GPU 或多张卡在彼此等待。
- 装得下吗? 内存或显存容量不足。
后面的所有术语,都是为回答这四个问题服务的。
先建立一个心智模型
把计算机想成一家餐厅:
| 计算机概念 | 餐厅里的角色 | 真正要关注的事 |
|---|---|---|
| CPU | 经验丰富的主厨 | 擅长复杂、变化多的任务 |
| GPU | 大量分工一致的厨师 | 擅长同时重复同一种操作 |
| 寄存器 / Cache | 手边和操作台上的食材 | 很快,但放不下太多 |
| 内存 / 显存 | 后厨仓库 | 容量更大,取用更慢 |
| SSD | 楼下的大仓库 | 容量很大,搬运耗时 |
| PCIe / NVLink / 网络 | 传送带和运输道路 | 决定数据搬运速度 |
| CUDA / OpenMP / MPI | 排班和协作规则 | 告诉不同工人如何分工 |
这个类比不负责解释所有细节,但能帮你判断一个新名词处于哪一层、解决什么问题。
推荐路线:先主干,后支线
历史原文入口说明
本目录保存课程重组前的体系结构与高性能原文。
它用于:
- 恢复旧链接;
- 查找原始图示;
- 核对旧代码;
- 比较术语变化;
- 追踪课程合并;
- 保留实验与面试问答。
最新学习顺序和勘误以当前权威课程为准。
历史内容的使用方法
current course
-> establish current concept and terminology
historical original
-> recover examples and earlier explanation
official documentation
-> verify version-sensitive facts不要把旧硬件参数和旧工具命令直接当作当前保证。
章节 1:计算机架构基础
本章建立“指令必须等待数据”的核心直觉。
阅读重点:
- CPU 执行指令;
- 寄存器与 Cache;
- 主存和存储;
- 延迟与带宽;
- 数据局部性;
- 性能测量。
完成后应能解释为什么同样的计算,不同访问顺序可能有巨大差异。
章节 2:并行计算理论
本章解释为什么增加资源不会无限加速。
重点:
- Work 与关键路径;
- Amdahl;
- Gustafson;
- 加速比;
- 并行效率;
- 强弱扩展;
- 通信和同步。
公式必须与固定工作量和测量口径一起使用。
章节 3:GPU 架构
本章解释 GPU 为什么用大量线程追求吞吐。
重点:
- SM;
- Warp;
- 调度;
- 分支发散;
- 寄存器;
- 共享内存;
- 全局内存;
- Occupancy。
Occupancy 是资源驻留指标,不是最终性能分数。
章节 4:CUDA 编程模型
CUDA 把 Host 程序和 Device Kernel 连接起来。
重点:
- Grid/Block/Thread;
- 线程索引;
- Kernel 启动;
- 同步范围;
- 错误检查;
- Stream;
- 设备选择;
- 端到端时间。
章节 5:CUDA 内存
本章关注数据如何到达 GPU 执行单元。
重点:
- Global Memory;
- Shared Memory;
- Register;
- Constant/Texture;
- Pinned Memory;
- Unified Memory;
- 合并访问;
- 数据传输。
章节 6:CUDA 优化
优化从 Nsight 证据开始。
检查:
- CPU/GPU 时间线;
- Kernel 占比;
- Warp Stall;
- Memory SOL;
- Compute SOL;
- 数据传输;
- 启动间隙;
- 正确性。
不要把固定阈值当作所有 GPU 的通用结论。
章节 7:OpenMP 与 SIMD
本章连接 CPU 线程和向量单元。
重点:
- Parallel Region;
- Loop Scheduling;
- Reduction;
- Data Sharing;
- SIMD;
- False Sharing;
- NUMA;
- 线程亲和性。
章节 8:MPI 与 HPC
MPI 使用独立进程和消息扩展到多节点。
重点:
- Rank;
- Communicator;
- Point-to-Point;
- Collective;
- Domain Decomposition;
- Halo;
- Latency/Bandwidth;
- Checkpoint。
章节 9:异构计算
异构计算设计 CPU 与加速器之间的任务和数据流。
CPU control and irregular work
-> batch transfer
-> accelerator kernel
-> overlap independent work
-> synchronize required result频繁往返会抵消加速收益。
章节 10:训练优化
训练性能由计算、通信、内存和数据管线共同决定。
重点:
- Mixed Precision;
- Data/Model/Pipeline Parallel;
- Optimizer State;
- Activation;
- Gradient Communication;
- Checkpoint;
- Data Loader;
- GPU 利用时间线。
章节 11:性能分析工具
历史文章最初集中于 Nsight 与 PyTorch Profiler。
当前工具指南还加入:
- WPR;
- WPA;
- Intel VTune Hotspots;
- VTune Threading;
- VTune Memory Access;
- Microarchitecture Exploration。
参见当前 性能分析工具。
章节 12:NPU
NPU 评估不能只看 TOPS。
检查:
- 数据类型;
- 算子覆盖;
- 动态形状;
- 内存;
- 编译器;
- Host 回退;
- 工具链;
- 实际模型延迟和吞吐。
章节 13:未来趋势
判断新技术时继续使用三条主线:
compute
memory and storage
communication新硬件是否有效,取决于完整应用能否使用,而不是单项峰值。
历史实验复现
复现旧实验前记录:
- 原提交;
- 编译器;
- CUDA/驱动;
- 硬件;
- 输入;
- 命令;
- 线程与设备;
- 原始结果;
- 当前差异。
无法复原环境时,应把结果标为历史参考。
历史代码迁移
迁移步骤:
- 先理解原例子要证明什么;
- 固定正确性测试;
- 更新构建与 API;
- 保留原实现对照;
- 重新测量;
- 说明语义变化;
- 把现代版本放入当前课程。
不要无记录覆盖原代码。
阅读完成标准
读者应能:
- 沿计算、存储、通信定位概念;
- 区分 CPU、GPU、NPU 的执行特点;
- 解释并行扩展限制;
- 设计基本性能实验;
- 选择 WPR/WPA、VTune 或 Nsight;
- 区分历史结论与当前事实;
- 找到对应权威文章;
- 用 Git 验证来源。
第一遍:建立直觉(约 2~3 小时)
按顺序只读每章的“先抓住直觉”和“升华/核心记忆点”:
- 计算机架构基础:为什么数据位置会影响速度
- 并行计算理论:为什么加机器不等于等比例变快
- GPU 架构:GPU 为什么适合大量重复计算
- CUDA 编程模型:代码如何变成许多 GPU 线程
- CUDA 内存:为什么“搬数据”常比“做计算”更贵
这一遍遇到公式、具体型号参数和完整代码,可以先跳过。
第二遍:学会定位与优化
- 性能分析工具:先用证据判断时间花在哪里
- CUDA 性能优化:针对计算、访存和调度瓶颈下手
- CPU 并行:OpenMP 与 SIMD:别让 CPU 端拖住 GPU
- CPU 与 GPU 协同:让搬运和计算重叠
注意:性能分析应当先于优化。原编号保留,是为了不破坏已有链接。
第三遍:扩展到训练和集群
- MPI 与 HPC 集群:多机多卡为何受通信限制
- 深度学习训练优化:把硬件原理落到训练配置
- NPU 全景:理解不同加速器的共同点与生态差异
- 未来趋势:用“计算、存储、通信”判断新技术
一个概念应该学到什么程度
每遇到一个术语,不要先背定义,按这个顺序理解:
- 它解决什么问题? 例如 Shared Memory 用来减少慢速显存访问。
- 不用它会怎样? 线程会反复从 Global Memory 搬同一批数据。
- 它付出什么代价? Shared Memory 容量有限,还需要线程同步。
- 什么时候该用? 多个线程会重复使用同一小块数据时。
- 最后才是怎么写。 再看 API、关键字和代码模板。
能用自己的话回答前四问,就算真正理解;型号数字、命令参数和 API 可以随用随查。
贯穿全篇的小例子
我们用“向量相加”建立最小模型:
c[0] = a[0] + b[0]
c[1] = a[1] + b[1]
c[2] = a[2] + b[2]
...每一行互不依赖,因此可以分给不同工人同时计算。由它可以逐步引出:
- CPU 单核:一个工人依次完成;
- CPU 多核 / SIMD:少量工人一次处理多份数据;
- GPU:成百上千个轻量线程共同完成;
- CUDA:描述这些 GPU 线程如何编号和访问数据;
- 多 GPU:先切分任务,完成后再交换或汇总结果;
- 性能优化:判断时间到底花在加法、搬运还是等待上。
带着这个小例子进入正文,比一上来想象 175B 模型更容易。大模型训练只是同一组原理在更大规模上的应用。
阅读约定
- 先抓住直觉:不依赖术语的解释,第一次阅读重点看。
- 必须理解:会影响后续章节的主干知识。
- 用到再查:型号参数、API 和工具命令,不要求背诵。
- 深入阅读:解释原理边界,第一遍可以跳过。
准备好了就从 第 0 章:全景学习路线 开始;如果只想快速入门,可直接进入 第 1 章。