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

外观

本页目录

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

这套笔记不是硬件名词词典。它只围绕一个问题展开:

一段程序为什么慢,我们能从哪里把时间省下来?

先别急着记 CUDA Core、Warp、HBM 和 NCCL。面对任何性能问题,先问下面四句话:

  1. 算得慢吗? 算术单元来不及完成工作。
  2. 取得慢吗? 数据没有及时送到计算单元。
  3. 等得久吗? CPU、GPU 或多张卡在彼此等待。
  4. 装得下吗? 内存或显存容量不足。

后面的所有术语,都是为回答这四个问题服务的。

先建立一个心智模型 ​

把计算机想成一家餐厅:

计算机概念餐厅里的角色真正要关注的事
CPU经验丰富的主厨擅长复杂、变化多的任务
GPU大量分工一致的厨师擅长同时重复同一种操作
寄存器 / Cache手边和操作台上的食材很快,但放不下太多
内存 / 显存后厨仓库容量更大,取用更慢
SSD楼下的大仓库容量很大,搬运耗时
PCIe / NVLink / 网络传送带和运输道路决定数据搬运速度
CUDA / OpenMP / MPI排班和协作规则告诉不同工人如何分工

这个类比不负责解释所有细节,但能帮你判断一个新名词处于哪一层、解决什么问题。

推荐路线:先主干,后支线 ​

从源码到硬件的完整路径 ​

text
source code
  -> compiler and linker
  -> executable instructions
  -> operating-system process and threads
  -> CPU pipeline / GPU kernel
  -> cache and memory
  -> storage, device and network
1
2
3
4
5
6
7

性能问题可能来自任何一层。

源码循环看起来简单,编译器可能没有向量化。 线程很多,调度器可能让它们争用少量核心。

CPU 指令执行很快,Cache Miss 可能让流水线等待。 GPU Kernel 很快,Host/Device 传输可能占总时间大部分。

所以先画端到端路径,再选择工具。

CPU 的定位 ​

CPU 擅长:

  • 复杂控制流;
  • 低延迟任务;
  • 操作系统服务;
  • 不规则数据结构;
  • 少量强线程;
  • 串行关键路径;
  • 任务调度与协调。

现代 CPU 使用流水线、乱序执行、分支预测、多级 Cache 和 SIMD。

单核性能受指令依赖、前端、执行端口、分支和内存共同影响。

GPU 的定位 ​

GPU 擅长:

  • 大规模数据并行;
  • 规则控制流;
  • 高吞吐;
  • 矩阵和向量;
  • 图像与网格;
  • 可批量 Kernel;
  • 高带宽设备内存。

GPU 通过大量 Warp 隐藏延迟。 线程不足、分支发散和不规则访存都会降低效率。

内存层次 ​

text
Registers
  -> L1 / Shared Memory
  -> L2 / LLC
  -> DRAM / HBM
  -> PCIe / NVLink / Network
  -> SSD / Object Storage
1
2
3
4
5
6

越靠近计算单元,延迟通常越低、容量越小。

优化要减少数据移动,提高复用,并让访问符合硬件粒度。

延迟与带宽 ​

延迟是单次操作完成需要多久。 带宽是单位时间能传输多少数据。

随机依赖访问更受延迟限制。 连续大块访问更容易受带宽限制。

增加并行度可以隐藏部分延迟,但无法突破持续带宽上限。

算术强度 ​

算术强度表示每搬运一个字节完成多少操作。

text
arithmetic intensity = operations / bytes
1

低强度 Kernel 常受数据移动限制。 高强度 Kernel 才更可能受计算吞吐限制。

Roofline 用算术强度连接算法和硬件上限。

CPU 并行层次 ​

CPU 并行包括:

  • 指令级并行;
  • SIMD;
  • SMT;
  • 多核线程;
  • 多插槽 NUMA;
  • 多进程;
  • 集群 MPI。

层次越多,数据分区和同步越重要。

GPU 并行层次 ​

text
Grid
  -> Block
  -> Warp
  -> Thread
1
2
3
4

Block 是协作和调度边界。 Warp 共享执行指令,分支发散会让路径串行化。

线程通过寄存器、共享内存和全局内存交换或访问数据。

CUDA 的学习重点 ​

学习 CUDA 不只记 API。

需要理解:

  • 线程索引;
  • 越界保护;
  • Block 大小;
  • 同步范围;
  • 内存空间;
  • 合并访问;
  • 共享内存;
  • Stream;
  • 异步拷贝;
  • 错误检查;
  • Kernel 与端到端测量。

OpenMP 与 SIMD ​

OpenMP 快速表达共享内存并行。

它适合规则循环和任务,但仍需理解:

  • 数据作用域;
  • Reduction;
  • Scheduling;
  • False Sharing;
  • NUMA;
  • 嵌套并行;
  • 线程数量;
  • 同步开销。

SIMD 与线程可以组合。 外层分块给线程,内层连续循环给向量单元。

MPI 与集群 ​

MPI 进程拥有独立地址空间,通过消息通信。

text
partition
  -> local compute
  -> exchange halo / collective
  -> synchronize required dependency
  -> continue
1
2
3
4
5

扩展受串行区、消息延迟、带宽、分区和最慢 Rank 限制。

异构计算 ​

CPU、GPU 和加速器共同完成工作。

设计重点不是“把代码放到 GPU”,而是:

  • 哪层拥有数据;
  • 哪个设备执行;
  • 何时搬运;
  • 是否可以重叠;
  • 何时同步;
  • 如何处理失败;
  • 结果在哪里提交。

NPU 与专用加速器 ​

NPU 针对特定张量运算和精度优化能效。

评估时检查算子覆盖、动态形状、内存、编译、回退和生态。 TOPS 是峰值指标,不是模型端到端吞吐。

性能分析工具路线 ​

text
system timeline
  -> stage and wait attribution
  -> function / kernel hotspot
  -> microarchitecture or memory detail
  -> change one factor
  -> same end-to-end benchmark
1
2
3
4
5
6

Windows 可使用 WPR/WPA 观察 ETW 时间线。 Intel CPU 可使用 VTune 做 Hotspots、Threading 和 Memory Access。

NVIDIA GPU 使用 Nsight Systems 与 Nsight Compute。 框架级训练可使用 PyTorch Profiler,再下钻到系统工具。

性能实验最小协议 ​

每次实验记录:

  • Git 提交;
  • 构建参数;
  • 硬件;
  • 输入;
  • 线程/进程/设备;
  • 预热;
  • 样本;
  • 正确性;
  • 原始结果;
  • 结论范围。

一次运行和一张截图不能证明优化。

典型错误 ​

  • 先优化后测量;
  • 用 Debug 构建;
  • 只看利用率;
  • 忽略数据传输;
  • 线程越多越好;
  • Occupancy 越高越好;
  • 把理论峰值当实际目标;
  • 用小输入推断大规模;
  • 改变正确性换取速度;
  • 优化后不做回归。

推荐实验 ​

  1. 数组顺序与随机访问;
  2. 工作集跨 Cache;
  3. AoS 与 SoA;
  4. 单线程与 SIMD;
  5. 线程扩展曲线;
  6. 伪共享;
  7. NUMA 首次触碰;
  8. GPU 合并访存;
  9. Kernel 与传输分项;
  10. MPI 强弱扩展;
  11. WPR/WPA 线程等待;
  12. VTune Hotspots 与 Memory Access。

每个实验都要先写假设,再保存原始样本。

第一遍:建立直觉(约 2~3 小时) ​

按顺序只读每章的“先抓住直觉”和“升华/核心记忆点”:

  1. 计算机架构基础:为什么数据位置会影响速度
  2. 并行计算理论:为什么加机器不等于等比例变快
  3. GPU 架构:GPU 为什么适合大量重复计算
  4. CUDA 编程模型:代码如何变成许多 GPU 线程
  5. CUDA 内存:为什么“搬数据”常比“做计算”更贵

这一遍遇到公式、具体型号参数和完整代码,可以先跳过。

第二遍:学会定位与优化 ​

  1. 性能分析工具:先用证据判断时间花在哪里
  2. CUDA 性能优化:针对计算、访存和调度瓶颈下手
  3. CPU 并行:OpenMP 与 SIMD:别让 CPU 端拖住 GPU
  4. CPU 与 GPU 协同:让搬运和计算重叠

注意:性能分析应当先于优化。原编号保留,是为了不破坏已有链接。

第三遍:扩展到训练和集群 ​

  1. MPI 与 HPC 集群:多机多卡为何受通信限制
  2. 深度学习训练优化:把硬件原理落到训练配置
  3. NPU 全景:理解不同加速器的共同点与生态差异
  4. 未来趋势:用“计算、存储、通信”判断新技术

一个概念应该学到什么程度 ​

每遇到一个术语,不要先背定义,按这个顺序理解:

  1. 它解决什么问题? 例如 Shared Memory 用来减少慢速显存访问。
  2. 不用它会怎样? 线程会反复从 Global Memory 搬同一批数据。
  3. 它付出什么代价? Shared Memory 容量有限,还需要线程同步。
  4. 什么时候该用? 多个线程会重复使用同一小块数据时。
  5. 最后才是怎么写。 再看 API、关键字和代码模板。

能用自己的话回答前四问,就算真正理解;型号数字、命令参数和 API 可以随用随查。

贯穿全篇的小例子 ​

我们用“向量相加”建立最小模型:

text
c[0] = a[0] + b[0]
c[1] = a[1] + b[1]
c[2] = a[2] + b[2]
...
1
2
3
4

每一行互不依赖,因此可以分给不同工人同时计算。由它可以逐步引出:

  • CPU 单核:一个工人依次完成;
  • CPU 多核 / SIMD:少量工人一次处理多份数据;
  • GPU:成百上千个轻量线程共同完成;
  • CUDA:描述这些 GPU 线程如何编号和访问数据;
  • 多 GPU:先切分任务,完成后再交换或汇总结果;
  • 性能优化:判断时间到底花在加法、搬运还是等待上。

带着这个小例子进入正文,比一上来想象 175B 模型更容易。大模型训练只是同一组原理在更大规模上的应用。

阅读约定 ​

  • 先抓住直觉:不依赖术语的解释,第一次阅读重点看。
  • 必须理解:会影响后续章节的主干知识。
  • 用到再查:型号参数、API 和工具命令,不要求背诵。
  • 深入阅读:解释原理边界,第一遍可以跳过。

准备好了就从 第 0 章:全景学习路线 开始;如果只想快速入门,可直接进入 第 1 章。

最后更新于:

Pager
下一篇← 系统与高性能 / Systems & Performance

持续记录,持续成长

Copyright © Tidenflow