3、GPU架构精讲:SIMT模型、Warp调度、显存层次与CUDA核心

聊到GPU架构,很多人第一反应就是“并行计算”。但到底怎么个并行法?为什么GPU能跑AI,CPU就不行?

我个人习惯把GPU看作一个“超级听话的流水线工厂”。CPU是几个全能老师傅,什么活都能干,但人少。GPU呢?是一大群只会干重复活的工人,但人多到吓人。你想想看,训练一个AI模型,本质上就是海量的矩阵乘法,全是重复劳动。这不就是给GPU量身定做的吗?

3.1 SIMT模型:单指令多线程的魔法

GPU最核心的思想,叫SIMT(Single Instruction, Multiple Threads)。

说白了就是:一个指挥官喊一句“立正”,底下几万个士兵同时做“立正”这个动作。指令只有一条,但执行的人有成千上万个。

这和CPU的SIMD(单指令多数据)有点像,但更灵活。SIMD要求数据必须整整齐齐排好队,像阅兵方阵。SIMT允许每个线程有一点点自己的小动作,比如有的线程可以走快一步,有的可以走慢一步。当然,走慢的会被强制等待,直到大家同步。

关键点:SIMT模型让程序员感觉自己在写多线程程序,但底层硬件其实是在用SIMD的方式批量执行。这种“假装是MIMD,其实是SIMD”的设计,是GPU性能爆发的核心秘密。

我在项目中遇到过一个问题:有个同事写了一个核函数,里面有个if-else分支。结果性能直接腰斩。为什么?因为SIMT要求同一个warp里的线程必须走同一个执行路径。遇到分支,硬件会先执行if的那一路,再执行else的那一路。线程多的那一半干活,另一半干等着。这就是所谓的“warp divergence”。

避坑指南:我曾经在一个图像处理项目里,因为没注意分支发散,导致性能从120fps掉到了40fps。后来我把分支条件改成了基于线程ID的掩码计算,性能立刻恢复。记住:在GPU里,少用if-else,多用三元运算符或掩码。

3.2 Warp调度:硬件线程管理的艺术

GPU里最小的执行单位不是单个线程,而是warp。NVIDIA的warp大小是32个线程。AMD的叫wavefront,是64个线程。

为什么是32?这不是拍脑袋定的。我记得早期设计时,工程师们发现32个线程刚好能填满一个SM(Streaming Multiprocessor)的执行单元,而且寄存器文件的读写带宽也刚好匹配。多了会浪费,少了会闲置。

warp调度的核心是“零开销上下文切换”。CPU切换线程要保存一堆寄存器,开销很大。GPU呢?每个warp有自己的寄存器文件,切换warp就是换个指针的事,几乎不花时间。

所以GPU的策略是:多放几个warp在SM里,当一个warp在等显存数据时,立刻切换到另一个warp执行。这叫“latency hiding”。

概念 CPU GPU
线程切换开销 高(几百个时钟周期) 几乎为零
隐藏延迟方式 大缓存 + 分支预测 大量线程切换
典型线程数 几十个 几万个

嗯,这里要注意:warp调度器在每个时钟周期都会选一个ready的warp发射指令。如果所有warp都在等数据,那SM就只能空转。所以,想要GPU跑满,你得保证有足够多的warp来“填满”延迟。

3.3 显存层次:从快到慢的存储金字塔

GPU的显存层次和CPU的缓存层次很像,但设计哲学完全不同。CPU的缓存是为了减少延迟,GPU的缓存是为了增加带宽。

从上到下,速度越来越慢,容量越来越大:

  • 寄存器(Register):最快,每个线程私有。一个SM有65536个寄存器,但分给每个线程后其实不多。我建议你写代码时尽量少用局部变量,多用寄存器变量。
  • 共享内存(Shared Memory):同一个block内的线程共享。速度接近寄存器,但容量只有几十KB。这是GPU编程的“黄金地带”,用好共享内存,性能翻倍不是梦。
  • L1缓存:和共享内存共用同一块物理存储,可以配置比例。我习惯把L1设小一点,共享内存设大一点,因为共享内存是程序员可控的。
  • L2缓存:所有SM共享,容量几MB。主要用来缓存全局内存的访问。
  • 全局内存(Global Memory):就是显存,容量最大(几GB到几十GB),但延迟最高(几百个时钟周期)。

个人经验:我曾经优化一个矩阵乘法的核函数,一开始直接读写全局内存,带宽利用率只有20%。后来把数据分块加载到共享内存,再计算,带宽利用率直接飙到85%。说白了,GPU编程就是“搬运工”的艺术——把数据从慢的地方搬到快的地方,再计算。

3.4 CUDA核心:不是核心,是ALU

很多人以为CUDA核心就是GPU的“核心”,就像CPU的核心一样。其实不是。

CUDA核心本质上就是一个浮点运算单元(ALU),专门做加减乘除。一个SM里通常有几十到上百个CUDA核心。比如RTX 3090的SM里有128个CUDA核心。

但真正让GPU强大的,是这些CUDA核心能同时工作。一个SM可以同时发射多条指令,让不同的CUDA核心执行不同的操作。比如有的做加法,有的做乘法,有的做逻辑运算。

嗯,这里要澄清一个误区:CUDA核心的数量并不直接等于性能。因为还有Tensor Core(专门做矩阵运算的单元)、SFU(特殊函数单元)等。在AI训练中,Tensor Core的作用比CUDA核心大得多。

核心观点:CUDA核心是GPU的“肌肉”,但真正让肌肉发挥力量的,是warp调度器、共享内存和显存带宽这三者的协同。缺一个,性能都上不去。

最后,我画了一张图来总结GPU架构的核心逻辑。你看完应该能明白,为什么GPU能成为AI时代的算力基石。

GPU架构核心逻辑图 CPU (Host) 全局内存 (Global Memory / VRAM) GPC (图形处理簇) × N TPC (纹理处理簇) × M SM (流式多处理器) × K Warp调度器 CUDA核心 × 128 共享内存 寄存器文件 L1缓存 Host 显存 GPC TPC SM

这张图从顶到底展示了GPU的层级结构。CPU发指令给显存,显存把数据喂给GPC,GPC拆成TPC,TPC再分给SM。每个SM里,warp调度器负责分配任务,CUDA核心负责计算,共享内存和寄存器负责快速存取。

说白了,GPU就是一个巨大的“数据流水线工厂”。CPU是厂长,只负责下命令。GPU是工人,只管埋头干活。两者配合好了,算力就上来了。

最后说一句:理解GPU架构,不要只看硬件框图。你得从“数据怎么流动”的角度去想。数据从显存到SM,从SM到寄存器,从寄存器到CUDA核心,每一步都有延迟和带宽的限制。优化的本质,就是让数据尽量待在快的地方,少去慢的地方。


公众号:蓝海资料掘金营,微信deep3321