3、GPU硬件基础:GPU架构简史(从Kepler到Hopper)
聊GPU架构之前,我先问大家一个问题:你写代码的时候,有没有想过GPU里到底发生了什么?
说实话,我刚开始做AI训练时,觉得GPU就是个黑盒子。把数据扔进去,它算完吐出来就行。直到有一次,我写了个自定义算子,跑起来比CPU还慢……嗯,那次之后我才老老实实去啃架构手册。
今天我们就从Kepler一路聊到Hopper,把GPU的底裤扒开看看。
3.1 架构简史:从Kepler到Hopper
NVIDIA的GPU架构,大概每两年更新一代。我整理了一个简表,方便你快速建立时间线:
| 架构代号 | 发布年份 | 代表型号 | 关键特性 |
|---|---|---|---|
| Kepler (K) | 2012 | K80 | SMX单元、动态并行 |
| Maxwell (M) | 2014 | M40 | 低功耗、共享内存优化 |
| Pascal (P) | 2016 | P100 | NVLink 1.0、HBM2 |
| Volta (V) | 2017 | V100 | Tensor Core、独立线程调度 |
| Turing (T) | 2018 | T4 | RT Core、INT8推理加速 |
| Ampere (A) | 2020 | A100 | 第三代Tensor Core、MIG |
| Hopper (H) | 2022 | H100 | Transformer Engine、DPX指令 |
我个人习惯把Volta看作一个分水岭。Volta之前,GPU主要给图形学服务;Volta之后,AI训练成了第一优先级。你想想看,Tensor Core就是Volta开始引入的,这玩意儿直接让混合精度训练起飞了。
核心观点: 每一代架构都在解决上一代的瓶颈。Kepler解决了通用计算调度问题,Pascal解决了显存带宽问题,Volta解决了矩阵乘法效率问题,Ampere解决了多租户隔离问题,Hopper则专门针对Transformer做了优化。
3.2 SM与CUDA Core:GPU的“细胞”
GPU里最小的执行单元是什么?不是CUDA Core,而是SM(Streaming Multiprocessor)。
SM就像一个小型处理器,里面包含多个CUDA Core、共享内存、寄存器文件、调度器等。我打个比方:SM是一个工厂车间,CUDA Core就是车间里的工人。
不同架构的SM配置差异很大。我列一下常见的:
- Kepler SMX: 192个CUDA Core,但调度粒度是32线程的warp
- Maxwell SMM: 128个CUDA Core,分成4个处理块,更灵活
- Volta SM: 64个CUDA Core + 8个Tensor Core,独立线程调度
- Ampere SM: 64个CUDA Core + 4个第三代Tensor Core
- Hopper SM: 128个CUDA Core + 4个Tensor Core,但引入了DPX指令
这里有个坑,我曾经踩过:CUDA Core数量不等于并行度。你想想看,一个SM里有128个CUDA Core,但一次只能执行一个warp(32线程)的指令。为什么?因为指令发射单元有限。说白了,CUDA Core多是为了掩盖访存延迟,不是真的能同时跑那么多线程。
避坑指南: 我曾经在优化一个卷积算子时,拼命增加线程数,结果性能反而下降。后来发现是SM里的寄存器不够用了,导致寄存器溢出到本地内存。记住:每个SM的寄存器总量是固定的,线程越多,每个线程分到的寄存器越少。
3.3 显存层次结构:HBM、L2、L1
GPU的显存层次,说白了就是“速度换容量”的妥协。我画了一张图,帮你理解这个层次结构:
这张图你看懂了吗?从上到下,容量越来越大,速度越来越慢。寄存器最快,但每个线程只能分到几十个;HBM最慢,但容量有几十GB。
我重点说说HBM。HBM(高带宽显存)是Pascal时代引入的,它把多个DRAM die堆叠在一起,通过硅中介层连接到GPU核心。这样做的好处是:位宽极宽(4096位),带宽极高。A100的HBM2e带宽是2 TB/s,H100的HBM3带宽达到了3.35 TB/s。
但注意,HBM的延迟其实比GDDR还高一点。为什么?因为堆叠结构导致信号路径变长。所以GPU才需要L2缓存来“兜底”。
警告: 千万别以为显存带宽大就可以随便访存。我曾经有个项目,数据没做对齐,结果每次访存都跨HBM的channel,带宽利用率直接腰斩。记住:HBM是按channel访问的,连续地址要落在同一个channel里才快。
3.4 NVLink与NVSwitch:多卡互联的“高速公路”
单卡算力再强,也架不住模型越来越大。GPT-3有1750亿参数,一张A100的80GB显存根本放不下。这时候就需要多卡互联。
NVLink是NVIDIA的点对点互联技术。第一代NVLink(Pascal)单链路带宽是20 GB/s,到了第四代(Hopper)已经飙到450 GB/s。我算了一下,相当于PCIe 5.0 x16的7倍带宽。
但NVLink有个限制:一张卡只能连4~6条链路。如果卡多了,比如8卡、16卡,就需要NVSwitch来组网。
NVSwitch说白了就是一个超高速交换机。DGX A100里用了6个NVSwitch,把8张A100全互联起来,任意两张卡之间都有600 GB/s的带宽。DGX H100更夸张,用了4个第三代NVSwitch,带宽达到900 GB/s。
我画个拓扑图,帮你理解:
看到没?每张GPU通过NVLink连接到NVSwitch,NVSwitch再负责转发。这样任意两张卡之间都是“一跳”,延迟极低。
我个人的经验是:多卡训练时,通信模式决定了你的扩展效率。All-Reduce操作(比如梯度同步)对带宽要求极高,NVLink就是为这个设计的。如果你用PCIe做多卡通信,带宽只有NVLink的十分之一,训练效率会大打折扣。
实战建议: 做分布式训练时,尽量让通信发生在NVLink域内。比如8卡DGX,内部通信走NVLink,跨节点通信走InfiniBand。我曾经见过有人把梯度同步放在跨节点做,结果通信开销占了训练时间的60%……嗯,那场面,惨不忍睹。
最后说一句:Hopper架构引入了DPX指令,专门加速动态规划算法。虽然现在用得不多,但我预感未来在路径规划、生物信息学等领域会有大用。保持关注吧。
小技巧: 想知道你的GPU用了什么架构?在终端里跑 nvidia-smi --query-gpu=name --format=csv,然后去NVIDIA官网查对应架构。我每次拿到新机器都会先跑一下这个命令。
好了,GPU硬件基础就聊到这里。记住:理解架构不是为了炫技,而是为了写出更高效的代码。下次你写CUDA kernel时,想想SM怎么调度、显存怎么访问、多卡怎么通信——这些知识会帮你省下大把调优时间。