GPU 微架构:从晶体管到一次 GEMM 的完整数据流
一句话结论:GPU 是一台「用海量小计算单元换并发、用深存储层级换带宽」的吞吐机器。它所有构件——SM 内的调度器/寄存器/Shared Memory/Tensor Core、芯片级的 L2/内存控制器/HBM、系统级的 NVLink/NVSwitch——都在服务同一个目标:让 Tensor Core 永远有数据可吃、让数据永远在路上不空转。
本文以 H100(SXM5)为参考基准,对照 NVIDIA 官方白皮书逐条核对过数字。核对中发现原稿有六处需要更正,其中一处涉及 GEMM 数据流的核心步骤,已在文中以 ⚠️ 标注。
一、全景:从晶体管到集群的层级堆叠
以 H100 SXM5 为参考:8 个 GPC → 66 个 TPC → 132 个 SM(每 TPC 2 个)→ 每 SM 128 个 FP32 CUDA Core + 4 个第四代 Tensor Core,配 5 个 HBM3 堆栈、50 MB L2、3.35 TB/s 显存带宽、80 GB 容量。
⚠️ SM 数量有三个版本,别混:H100 SXM5 = 132 SM、H100 PCIe = 114 SM、满配 GH100 芯片 = 144 SM(8 GPC × 9 TPC × 2)。本文数字均指 SXM5。
Blackwell 在同一套层级上把量级再拉一档:
| H100 SXM5 | B200 | |
|---|---|---|
| SM 数 | 132 | 148(整卡双 die) |
| L2 | 50 MB | 126 MB(GB200) |
| HBM | 80 GB HBM3 / 3.35 TB/s | 192 GB HBM3e / 8 TB/s |
| NVLink | 4.0 / 900 GB/s | 5 / 1.8 TB/s |
⚠️ 两处口径提示:一是 B200 的 148 SM 是整卡(双 die 合计),约 74 SM/die;二是 L2 = 126 MB 的官方出处是 GB200(Blackwell Tuning Guide 原文 “The NVIDIA GB200 GPU increases the L2 cache capacity to 126 MB”)。另外 B200 的显存容量存在官方口径分歧:微基准论文与常见资料写 192 GB,而 Blackwell Tuning Guide 与 DGX B200 页面按可用容量折算约 180 GB/GPU。引用时建议注明口径。
把所有构件的角色和量级钉死(数值以 H100 SXM5 为主):
| 构件 | 所在层级 | 容量 / 数量 | 作用 |
|---|---|---|---|
| CUDA Core(FP32/INT32) | SM 分区内 | 每 SM 128 个 | 标量 ALU,通用浮点/整数运算 |
| Tensor Core | SM 内 | 每 SM 4 个 | 专用矩阵乘累加(MMA),AI 算力主要来源 |
| Warp 调度器 + 分发单元 | SM 分区内 | 每分区 1 套 | 每 cycle 挑一个 ready 的 warp 发射指令 |
| 寄存器文件 | SM 分区内 | 256 KB / 64K×32-bit(每 SM) | 线程私有,零延迟,常是 kernel 瓶颈 |
| Shared Memory + L1 | SM 内统一 | 统一 256 KB,SMEM 可配至 228 KB | 线程块共享的 on-chip scratchpad |
| TMA | SM 内 | 每 SM 1 个 | 异步批量搬 tile 的地址生成硬件 |
| L2 Cache | 全芯片共享 | 50 MB(H100)/ 126 MB(GB200) | SM 与 HBM 之间的统一缓冲 |
| HBM3/3e | 芯片外 2.5D 封装 | 80—192 GB | 主显存,3.35—8 TB/s |
| 内存控制器 | 芯片内 | 10×512-bit | 连接 L2 与 HBM 通道 |
| NVLink / NVSwitch | 芯片间 / 机架 | 900 GB/s(NV4)/ 1.8 TB/s(NV5) | GPU↔GPU 高带宽互联 |
| PCIe Gen5 | 主机↔GPU | 128 GB/s | CPU↔GPU 数据进出通道 |
⚠️ 更正:原稿写「Shared Memory + L1 统一 228 KB」。官方原文是 L1 数据缓存与 Shared Memory 的统一容量为 256 KB/SM,其中 Shared Memory 本身可配置到 228 KB(单 CTA 最多寻址 227 KB)。228 KB 是 SMEM 的上限,不是统一容量。
一张图把物理包含关系画清楚(数据路径实线,封装关系虚线):
flowchart TD
GPU["GPU 芯片<br/>H100 SXM5: 8 GPC / 132 SM"] --> GPC["GPC 图形处理集群"]
GPU --> L2["L2 Cache(全片共享 50 MB)"]
GPU --> MCTL["内存控制器 10×512-bit"]
GPC --> TPC["TPC"]
TPC --> SM["SM 流式多处理器 ×2/TPC"]
SM --> P0["SM 分区 0-3<br/>各带 L0 i-cache、warp 调度器、<br/>分发单元、寄存器 64K×32-bit"]
SM --> L1S["L1 / Shared Memory<br/>统一 256 KB(SMEM 上限 228 KB)"]
SM --> TMA["TMA 张量内存加速器(每 SM 1 个)"]
SM --> TC["Tensor Core ×4(第 4 代)"]
P0 --> CC["CUDA Core ×32 FP32 / SM 分区"]
MCTL --> HBM["HBM3 堆栈 ×5<br/>80 GB / 3.35 TB/s"]
HBM -.2.5D CoWoS 封装.- INT["硅中介层 → GPU die"]
GPU <--> NVLINK["NVLink 4/5<br/>900 GB/s / 1.8 TB/s"]
NVLINK <--> NVSW["NVSwitch → 其他 GPU"]二、计算核心:SM 的内部解剖
SM(Streaming Multiprocessor)是 GPU 的灵魂——并行、调度、数据搬运都发生在 SM 内。它分三个逻辑组。
2.1 调度组:靠切换 warp 吃掉延迟
L0 i-cache → Warp 调度器 → 分发单元。 Hopper/Blackwell 的 SM 分成 4 个 sub-partition,每个分区有独立的 L0 指令缓存、Warp 调度器和 dispatch unit。
调度器按 scoreboard 每周期从驻留 warp 中挑一个操作数就绪的下发;遇到长延迟指令(访存)就切到别的 warp——靠切换 warp 来隐藏延迟。这是 GPU 吞吐模型的核心,也是它与 CPU 最本质的分野:CPU 用大缓存 + 分支预测压低单线程延迟,GPU 用海量 warp 的切换把延迟「填满」。
2.2 执行组:SIMT 与 warp divergence
CUDA Core 是通用 FP32/INT 标量 ALU,每 SM 128 个;每 32 个 Core 打包成一条 lane,对应一个 warp 的 32 个线程——这叫 SIMT 执行。
一个 warp 内如果走了不同分支,硬件不会并行跑两条路径,而是串行跑各条路径、关掉不参与的线程。这叫 warp divergence,是隐性吞吐杀手。
Tensor Core 是专为 MMA(matrix multiply-accumulate)设计的专用管线。Ampere 时代的形状是 mma.sync.m16n8k16——一条指令在一个周期内完成 16×8×16 的小矩阵乘加;Hopper 换成了 wgmma.m64nNk16 系列(N 可取 16/32/64/128/256),配合 FP8/FP4 微缩放格式把大模型算力拉到 PFLOPS 级。
⚠️ 更正:原稿只提了
mma.sync.m16n8k16。那是 Ampere 的形状,Hopper 的 WGMMA 是m64nNk16(fp16/bf16)、m64nNk8(tf32)、m64nNk32(fp8/int8)。这个区别在第 6 节的数据流里会变得很关键。
2.3 数据组:寄存器、Shared Memory 与 TMA
寄存器是每线程私有的 64K×32-bit 池(每 SM 256 KB)。分配公式大致是 max resident threads = 65536 / R——kernel 用 128 寄存器/线程时一个 block 最多 512 线程。
Shared Memory 和 L1 是同一块物理资源(统一 256 KB,可配比),被切成 32 个 bank。如果同一 warp 的多个线程同时命中同一 bank 的不同地址,就发生 bank conflict,访问被串行化,吞吐掉底。
TMA(Tensor Memory Accelerator) 是 Hopper 起加入的专用 DMA 硬件,每 SM 一个,由 CTA 内单个线程发起。它把多维张量的地址生成从 CUDA Core 和寄存器中解放出来。
⚠️ 更正:原稿说「TMA 指令是
cp.async.bulk」。cp.async.bulk是**一维(非张量)**批量拷贝;张量 TMA 用的是cp.async.bulk.tensor(配合 Tensor Map 描述符)。两者在 PTX 里并列存在。
再往上:GPC → TPC → SM 主要是物理分区。 一个 GPC 通常含 8—9 个 TPC,每个 TPC 含 2 个 SM,外加共享的光栅化/纹理管线(消费卡上用于图形,计算卡上主要是带宽与布线考虑)。这层在 CUDA 编程模型里基本对开发者透明。
三、存储层级:带宽悬崖
GPU 的性能一半靠算,一半靠把数据以最低延迟、最高带宽送到运算单元嘴边。
| 层级 | 容量(H100 SM) | 带宽量级 | 延迟(实测) | 延迟掩藏手段 |
|---|---|---|---|---|
| 寄存器 | 256 KB/SM | 最高 | 流水线语义(近零) | warp 间切换 |
| Shared Memory / L1 | 统一 256 KB(SMEM ≤228 KB) | 128 B/cycle/SM | ~29—33 cycle | async copy + 同步原语 |
| L2 Cache | 50 MB(全片) | 居中 | ~260—500 cycle | 缓存命中率 |
| HBM | 80 GB | 3.35 TB/s | ~650 cycle | TMA 预取 + persistent kernel |
| NVLink(他卡) | — | 900 GB/s/卡 | μs 级 | 通信/计算 overlap |
| PCIe(主机) | — | 128 GB/s | μs 级 | 异步 copy |
⚠️ 更正:原稿的延迟量级(SMEM 20—30 / L2 ~200 / HBM ~400+)方向对但普遍偏低。P-chase 微基准在 H800/A100 上的实测是:Shared Memory ~29—33 cycle、L2 ~260—500 cycle、HBM ~650 cycle。上表已按实测值更新。另外「寄存器 ~128 read/cycle」这个数字我没找到官方或权威来源,已从表中去掉。
带宽悬崖
on-chip SRAM 的总带宽远高于 HBM,中间这道落差就是所有 kernel 优化在对抗的对象。
⚠️ 更正(这处比较关键):原稿写「on-chip SRAM 总带宽约 19 TB/s」。19 TB/s 是 A100 的数字(128 B/cyc × 108 SM × 1.41 GHz ≈ 19.5 TB/s)。H100 约 31 TB/s——FlashAttention-3 论文明确给了这个值:“SMEM 228 KiB per SM, 31 TB/s per GPU”,算法是 128 B/cyc × 132 SM × 1830 MHz。引用时务必区分代际。
对应地,HBM 侧 1.5—3.35 TB/s 分别对应 A100(1.555 TB/s)与 H100 SXM(3.352 TB/s)。
HBM 的物理实现
3D 堆叠 + 2.5D 封装:每个 HBM 堆栈由多层 DRAM die 用 TSV 垂直互连组成,对外提供 1024-bit 的超宽总线;多个堆栈通过硅中介层与 GPU die 连接,采用 CoWoS 等先进封装。
H100 是 5 堆栈 × 1024 bit ≈ 5120-bit 总线(官方规格表写 “Memory Interface 5120-bit HBM3”,由 10 个 512-bit 内存控制器拼出),加上高频 DRAM 得到 3.35 TB/s。
这与 GDDR7 走的「高频窄总线」路线形成鲜明对比——HBM 靠宽度取胜,GDDR 靠频率取胜。
四、互联层:NVLink / NVSwitch / PCIe
单卡 HBM 已经放不下大模型,GPU 之间的互联成为算力的另一半。
PCIe Gen5(128 GB/s)是通用兼容通道,适合 CPU↔GPU 数据进出和一般通信,但在张量并行的 all-reduce 上远远不够。
NVLink 是 NVIDIA 的私有高带宽直连协议:NVLink 4.0 在 H100 上达 900 GB/s(18 条链路,每条每方向 25 GB/s 有效带宽);NVLink 5 在 B200 上达 1.8 TB/s。
NVLink 是点对点直连,但 GPU 数量超过单链路覆盖范围时就需要 NVSwitch 做全互联。DGX H100 里 8 张 H100 通过 4 颗 NVSwitch 全互联,任意两卡之间都是满带宽 900 GB/s;而 PCIe switch 会因树形拓扑导致带宽衰减。
⚠️ 更正:原稿写「H100 上每卡最多连 4—6 个 peer」,官方没有这个说法。实际是两种形态:8-GPU HGX/DGX H100 经 4 颗 NVSwitch 全互联,每卡对另外 7 卡都是 900 GB/s;4-GPU HGX H100 是直连,每卡 3 个 peer、点对点 300 GB/s 双向。
再往上,GB200 NVL72 用 NVLink Switch 把 72 张 GPU 连成一个 130 TB/s 的「大 GPU」——这是机架级训练/推理的基础。
五、代际演进与两个改变编程模型的硬件
Hopper → Blackwell 这条线上各构件的演化:SM 132 → 148(整卡)、L2 50 → 126 MB(GB200)、HBM3 80 GB/3.35 TB/s → HBM3e 192 GB/8 TB/s、NVLink 4 900 GB/s → NVLink 5 1.8 TB/s。
比数字更重要的是 Hopper 引入的两个编程模型层,它们改变了 SM 之间的协作方式。
5.1 Thread Block Clusters(TBC)与 DSMEM
Hopper 新增了一个层级:可以把多个 CTA(thread block)编为一个 cluster。官方口径是——可移植的 cluster 上限是 8;H100 允许通过 cudaFuncAttributeNonPortableClusterSizeAllowed 选入非可移植的 16。
cluster 内的 thread block 之间可以通过 DSMEM(Distributed Shared Memory) 直接读写彼此的 Shared Memory——官方白皮书原文解释了这个命名:“the shared memory’s virtual address space is logically distributed across all the Blocks in the Cluster”。
配合 TMA multicast(PTX 的 .multicast::cluster 限定符),可以让一个 leader CTA 发起一次 TMA,硬件从 L2 拉一次 tile、再用 SM-to-SM 的 crossbar 扇出到多个 SM 的 Shared Memory。GEMM 里 B 矩阵 tile 因此只需读一次 HBM。
5.2 异步 Warpgroup MMA(WGMMA)
Ampere 时代的 mma.sync 是同步的;Hopper 起变成异步——PTX 里就叫 wgmma.mma_async,在 async proxy 中执行。CUDA Core 可以一边发 WGMMA 一边继续搬下一块 tile,这催生了 persistent kernel(kernel 常驻 + tile 循环)的编程范式。
WGMMA 还有一处更根本的变化,直接决定了下一节的数据流怎么写——见 6.3。
六、一次 GEMM 的完整数据流
以 BF16 矩阵乘 C = A×B 为例。这是 FlashAttention、CUTLASS、cuBLAS 共用的骨架。
6.1 发起与分块
CPU 通过 PCIe 把 A/B 拷到 HBM(大模型训练时 A 已经在 HBM)。kernel launch 时 grid 被切成多个 tile,每个 CTA 负责一个 C tile;在 Hopper/Blackwell 上还会进一步把多个 CTA 编成 cluster,利用 TMA multicast 让多个 SM 共享同一 B tile。
6.2 TMA 异步加载 tile 到 Shared Memory
CTA 内一个线程发出 cp.async.bulk.tensor 指令,TMA 硬件按 Tensor Map 计算多维地址,把整块 tile 从 HBM → L2 → Shared Memory 异步搬运。CPU 完全不参与地址生成,寄存器零压力。
在等待 TMA 完成的空隙里,warp 调度器切到其他 ready 的 warp 继续执行——这就是 2.1 讲的延迟掩藏。
6.3 ⚠️ 关键更正:Hopper 上不再需要「先 load 到寄存器」
原稿在这一步写错了,而且这个错误会传导到整段数据流。 原稿第 3 步是:「Tensor Core 不能直接吃 Shared Memory 里的任意数据,需要先把 A、B 的子矩阵按 MMA 需要的布局(如 m16n8k16 的 fragment)load 到 warp 的寄存器里。」
这对 Ampere 及更早的 mma.sync 成立,对 Hopper 的 WGMMA 不成立。 PTX ISA 原文(§9.7.17.5.1):
The input matrix A of the warpgroup wide MMA operations can be either in registers or in the shared memory. The input matrix B of the warpgroup wide MMA operations must be in the shared memory.
也就是说,Hopper 的 WGMMA 直接用 64-bit 描述符(descA / descB)指向 Shared Memory 就能执行——B 必须走 SMEM,A 可选寄存器或 SMEM。微基准论文也印证了这点:“wgmma has the advantage of directly loading matrices A and B from shared memory, unlike mma, which requires storing all matrices in the register file before execution”。
所以 Hopper 上的 GEMM 数据流少了一步:TMA 把 tile 搬进 SMEM 后,WGMMA 可以直接消费。寄存器 fragment 加载只出现在 A 走寄存器的 “RS” 模式里。
这也解释了为什么 Hopper 的 kernel 写法与 Ampere 差别那么大——不是优化技巧变了,是数据通路本身变了。
6.4 Tensor Core 执行 MMA
wgmma.mma_async 让 warpgroup(128 线程)级的 Tensor Core 完成 m64nNk16 的乘加,结果累加到寄存器中的 C fragment。因为它是异步的,发射后不阻塞,CUDA Core 可以继续准备下一 k-block。
6.5 K-loop 循环累加
步骤 6.2—6.4 在 k 维度上循环(每次推进一个 k-tile),C fragment 在寄存器里持续累加、不落盘;与此同时 TMA 已经预取了下一个 k-tile 到 Shared Memory,形成 pipeline overlap。
6.6 Epilogue 写回
K 循环结束后,C tile 从寄存器经过 epilogue(可能的量化、非线性、rescale)写回 Shared Memory,或直接通过 TMA store 写回 HBM,也可以通过 DSMEM 广播给同 cluster 的其他 CTA 做后续归约。
6.7 通信阶段
如果是训练里的张量并行,这一步通过 NVLink/NVSwitch 做 all-reduce,同步分片梯度。kernel 与通信可以异步重叠——NVIDIA NeMo 有专门的 communication overlap 机制(ub_tp_comm_overlap=true),把 TP 的 all-gather / reduce-scatter 分块后与计算流水线化。
七、收束
整个流程里,性能瓶颈往往不在「算」(Tensor Core 很少打满),而在「喂」——HBM 带宽、Shared Memory bank conflict、寄存器压力、warp stall 这四个软肋决定了 kernel 的实际 TFLOPS。
这正是 FlashAttention-3、CUTLASS、cuBLAS 这些 kernel 工程的全部意义所在:它们的战场不在数学,在数据通路。
回到开头那句话——GPU 的所有构件,本质上都是在围绕「让 Tensor Core 永远有数据可吃、让数据永远在路上不空转」这个吞吐目标做分层设计。理解了这套层级及其带宽/延迟量级,就读懂了大模型训练和推理在硬件上真正发生的事情。
相关阅读
- Blackwell 与 Rubin:从路线图到训推优化——本文的姊妹篇,讲产品代际与优化主线
- GPU Kernel、异步 Launch、Stream 与融合 Kernel 全解——kernel 下发与流并行的工程视角
- 大模型显存计算法则——显存占用怎么算,与本文的存储层级互为补充
- AI Infra 全景复盘:GPU 性能、分布式训练与调度层深潜——Nsight 剖析流程与并行策略
- 一文搞懂 AI 推理部署算子融合——算子融合在软件栈上的落点
核实说明:本文所有硬件规格逐条核对自 NVIDIA 官方文档——H100 白皮书 V1.04(SM 数、寄存器、Shared Memory、L2、HBM 接口、NVLink)、Blackwell 架构技术简报 V2.1、CUDA C Programming Guide、PTX ISA、Hopper/Blackwell Tuning Guide、DGX H100 用户指南、HGX H100 博客。延迟与带宽实测数据取自 P-chase 微基准(arXiv:2501.12084)与 FlashAttention-3(arXiv:2407.08608)。原稿的六处更正已在文中以 ⚠️ 标注:SMEM/L1 统一容量、SRAM 带宽的代际口径、存储延迟量级、NVLink peer 数、TMA 指令名、以及 GEMM 数据流中「必须先 load 到寄存器」这一步在 Hopper 上已不成立。
