4. 硬件架构基础:NVIDIA GPU的SM、Warp、Tensor Core架构解析

聊GPU架构,很多人一上来就盯着显存带宽、算力这些数字看。我个人习惯,先看SM。为什么?因为SM才是GPU真正的计算核心,其他都是为它服务的。

说白了,一个NVIDIA GPU就是一堆SM的集合。每个SM都是一个独立的小型处理器,有自己的寄存器、共享内存、调度单元。你写的CUDA代码,最终就是在这些SM上跑的。

4.1 SM:GPU的心脏

SM的全称是Streaming Multiprocessor,流式多处理器。你可以把它理解成一个迷你CPU核心,但设计思路完全不同。

CPU核心追求单线程性能,有巨大的缓存、复杂的分支预测。SM追求的是吞吐量,它同时管理成百上千个线程。我刚开始接触CUDA时,总拿CPU的思路去优化GPU代码,结果性能惨不忍睹。后来才明白,SM的设计哲学就是「人多力量大」。

每个SM内部包含:

  • CUDA Core:执行整数和浮点运算的基本单元
  • Tensor Core:专门做矩阵乘法的加速单元
  • 共享内存:同一个Block内的线程可以访问
  • 寄存器文件:每个线程私有的高速存储
  • Warp调度器:负责把指令发给执行单元

嗯,这里要注意。不同代的GPU,SM内部结构差异很大。比如Ampere架构的SM有4个分区,每个分区包含16个INT32单元、16个FP32单元、8个FP64单元。而Hopper架构又做了调整。你写代码时,最好查一下目标GPU的具体参数。

4.2 Warp:GPU的调度单位

Warp是NVIDIA GPU最核心的概念之一。一个Warp包含32个线程,它们以SIMT(单指令多线程)方式执行。什么意思?就是32个线程执行同一条指令,但处理不同的数据。

我曾经踩过一个坑。写了一段代码,里面有个if-else分支。32个线程里,16个走if,16个走else。结果呢?性能直接腰斩。因为Warp内的线程必须执行相同的指令,遇到分支时,一部分线程执行,另一部分就得等着。

关键点:Warp是GPU调度的最小单位。一个Warp内的线程必须同步执行。如果出现分支发散,性能会严重下降。

为什么会这样?因为SM里的Warp调度器一次只能给一个Warp发指令。它把32个线程绑在一起,统一调度。你想想看,如果32个人要干两件不同的事,那只能先让16个人干完,再让另外16个人干。效率自然低。

所以写CUDA代码时,我建议你尽量保证Warp内线程的执行路径一致。实在避免不了分支,那就让分支尽量简单,或者用三元运算符替代if-else。

4.3 Tensor Core:AI计算的加速引擎

Tensor Core是NVIDIA在Volta架构引入的专用硬件单元。它专门做矩阵乘法累加运算,也就是D = A × B + C。这个操作在深度学习里太常见了,全连接层、卷积层、注意力机制,本质上都是矩阵运算。

我记得第一次用Tensor Core时,被它的性能吓了一跳。同样是做矩阵乘法,用CUDA Core需要几百个时钟周期,Tensor Core一个周期就能完成4×4矩阵的乘法累加。这差距,简直不是一个时代的产物。

Tensor Core的工作原理是这样的:

  • 输入矩阵A和B是半精度浮点数(FP16)
  • 累加矩阵C可以是FP16或FP32
  • 输出矩阵D的精度取决于累加矩阵

你可能会问,为什么用半精度?因为AI模型对精度的要求没那么高。FP16的数值范围虽然小,但做推理和训练足够了。而且半精度数据占用的显存少,带宽需求低,计算速度更快。

实战技巧:使用Tensor Core时,记得用cublasGemmEx或cuBLASLt API。手动写WMMA(Warp Matrix Multiply Accumulate)代码虽然灵活,但调试起来很痛苦。我建议先用库函数,性能瓶颈时再考虑手写。

4.4 三者如何协同工作

SM、Warp、Tensor Core不是孤立的。它们之间的关系,我画了一张图来说明:

SM (Streaming Multiprocessor) Warp Scheduler 指令分发单元 Warp Pool 最多64个Warp CUDA Core 阵列 FP32 / INT32 / FP64 每个Warp 32个线程并行执行 Tensor Core 4×4 矩阵乘法累加 FP16 / BF16 / INT8 共享内存 (Shared Memory)

这张图展示了一个SM内部的工作流程:

  1. Warp调度器从Warp Pool中选取一个就绪的Warp
  2. 根据指令类型,将Warp分发给CUDA Core或Tensor Core
  3. 执行单元完成计算后,结果写入共享内存或寄存器
  4. 共享内存作为Block内线程的通信桥梁

实际运行时,SM会同时管理多个Warp。当一个Warp在等待内存访问时,调度器会立刻切换到另一个Warp。这种机制叫「零开销上下文切换」,是GPU高吞吐量的关键。

避坑指南:我曾经在项目里遇到一个性能问题,显存带宽利用率只有30%。排查了半天,发现是共享内存使用过多,导致每个SM上活跃的Warp数量减少。记住,共享内存是有限的,用多了会限制并行度。

4.5 不同架构的差异

NVIDIA的GPU架构一直在演进。我整理了一个表格,方便你对比:

架构 SM内分区 每个SM的CUDA Core Tensor Core版本 共享内存大小
Volta (V100) 4个分区 64 FP32 + 64 INT32 第1代 96 KB
Turing (T4) 4个分区 64 FP32 + 64 INT32 第2代 64 KB
Ampere (A100) 4个分区 64 FP32 + 64 INT32 + 32 FP64 第3代 192 KB
Hopper (H100) 4个分区 128 FP32 + 64 INT32 第4代 228 KB

从表格可以看出,Tensor Core的迭代速度很快。第4代Tensor Core支持了FP8精度,进一步提升了AI计算的效率。我建议你在选择GPU时,优先考虑Tensor Core的代数,它对AI workloads的影响最大。

嗯,最后说一句。理解SM、Warp、Tensor Core的架构,是写出高性能CUDA代码的基础。你不需要记住每个细节,但一定要明白它们的设计意图。SM追求吞吐量,Warp是调度单位,Tensor Core是AI加速器。这三者配合好了,你的程序才能跑出接近理论峰值的性能。

核心总结

  • SM是GPU的计算核心,管理数百个线程
  • Warp是32个线程的集合,是调度和执行的单位
  • Tensor Core是专用矩阵乘法单元,大幅提升AI计算效率
  • 避免Warp发散,合理使用共享内存,是优化的关键
专注资料整理