Vol.1 建立了一个 GPU 的公约数模型:SIMT 执行抽象、Scoreboard 驱动的 warp scheduling、Operand Collector + Register File 构成的操作数供给路径、多级 Memory Hierarchy 的延迟隐藏与带宽放大机制,以及 Function Feature 如何在这套骨架上生长出图形与计算的差异化能力。那个模型是抽象的,回答的是"一个 GPU 为了吞吐导向的执行必须解决哪些问题",但不涉及任何具体厂商的硬件实现。
这一篇把那个抽象模型落地到 NVIDIA 的硬件实现中。Tesla 统一寻址把顶点、像素、几何三条固定管线合并进同一套 SM 阵列,false dependency 却让多个 CUDA Stream 在硬件队列里被强制串行化。从 2006 年 Tesla(G80)到 2024 年 Blackwell(GB200),每一代都在公约数模型的同一组维度上做出不同的取舍:ISA 编码与调度信息的耦合方式、Scoreboard 的硬件/编译器职责划分、执行单元的分离与统一、Register File 容量与 Occupancy 的约束链、三条访存通路的合并节奏、以及固定功能与可编程路径的边界移动。这些取舍在不同工艺节点和工作负载压力下反复发生,构成八代架构的技术主线。
分析范围限定在 GPU die 内部与 graphics / compute / RT execution 直接相关的 architecture / microarchitecture。多 GPU 互联(NVLink / NVSwitch)、平台级扩展(DGX / GB200 NVL72)及 CPU-GPU 集成(Grace-Hopper)不在主线讨论范围内。
一、Tesla(2006–2009)
Tesla 是 NVIDIA GPU 从固定功能图形加速器向通用并行计算平台转型的起点。G80(2006)引入的 Unified Shader Architecture 与 SIMT 执行模型构成一次执行范式切换:从"为每个着色阶段定制硬件"变为"一套同构 SM 阵列 + 线程级调度覆盖所有工作负载"。切换的直接原因是工作负载的不确定性:DirectX 10 引入 Geometry Shader 后,顶点、几何、像素三个阶段的相对负载在运行时才可确定,固定划分硬件资源的设计在利用率上已触及天花板。
对微架构分析而言,Tesla 奠定了 NVIDIA 后续近二十年 SM 内部结构的原型:标量 SP 阵列、warp-based scheduling、巨型 Register File、软件管理的 Shared Memory、三条分离的访存通路。后面每一章都会回到这个原型,看它被动了哪一刀。
1.1 ISA
Tesla 的指令集架构在软件层和硬件层之间存在明确的两级抽象:PTX(Parallel Thread Execution)是虚拟 ISA,面向编译器和程序员。SASS(Shader Assembly)是硬件实际执行的机器码。PTX 提供跨代架构的兼容性保证,由驱动中的 ptxas 编译器将 PTX 翻译为特定 Compute Capability(CC)的 SASS。这一分层使硬件 ISA 可以相对自由地演进:只要不破坏 PTX 语义,SASS 的编码格式、指令延迟、端口约束都可以随架构改变。
标量 ISA 与 SIMT 的硬件契约
Tesla 的 SM 执行标量指令,每个指令槽位仅操作单个线程的一个 32-bit 数据。这与早期 GPU 的 4-component 向量指令(RGBA / XYZW)有根本区别:向量指令要求编译器将操作对齐到向量通道,且在线程控制流复杂时易出现通道闲置。标量 ISA 将并行性的管理从编译器推给硬件:编译器只需生成单线程代码,硬件通过 SIMT 机制将 32 个标量线程打包为一个 Warp 同步执行。
硬件基础有三:
- 指令存储侧:Warp 内 32 个线程共享一个 Program Counter,I-Cache 按 warp 粒度取指,而非为每个线程单独维护 PC。
- 执行侧:标量 SP 阵列以时间复用方式覆盖 warp 的 32 个线程(8 SP × 4 cycle = 32 thread),每个 SP 在 4 个周期内顺序处理 4 个线程的同一指令。
- 控制流侧:Branch Synchronization Stack 管理 warp 内线程的分支发散与汇合,硬件通过 Activity Mask 串行化不同执行路径。
标量 ISA 为 SIMT 提供了关键的灵活性:同一 warp 内不同线程可以携带不同的谓词状态走不同路径,而向量 ISA 要求所有线程在同一指令下对向量通道做相同操作。
指令集构成
Tesla SASS 的指令可按功能分为五类:
算术指令: FP32 MAD(Multiply-Add)、ADD、MUL。32-bit 整数 ADD、SUB、逻辑运算。特殊函数指令(SIN、COS、EX2、LG2、RCP、RSQ)。MAD(Multiply-Add)是 Tesla 最频繁使用的浮点指令,单周期吞吐(per SP),延迟约 4 cycle。Tesla/G80/GT200 的 FP32 主路径为 MAD,而非 FMA。IEEE 754-2008 的 single-precision FMA、subnormal handling 与 directed rounding 等数值语义升级应归入 Fermi。SFU 指令(RCP、RSQ、SIN、COS 等)走独立的 SFU pipeline,延迟 12-16 cycle,吞吐每周期每 SFU 一个结果。
谓词与分支指令: Tesla 引入 4 个 Predicate Register per thread,每条指令可附加谓词条件决定是否执行。短分支通过谓词化执行避免 Branch Synchronization Stack 的压栈/弹栈开销。长分支或嵌套分支则必须使用硬件堆栈管理。BRA(分支跳转)、BRK(循环退出)、SSY(同步点标记)等指令由分支执行单元处理。
内存指令: LD/ST(全局/局部/共享内存)、TEX(纹理采样)、MOV(常量内存读取)。每种内存空间对应独立的硬件通路和延迟特征:
ld.global/st.global:经 Memory Coalescing Unit → Memory Controller → GDDR,延迟 400-600 cycle,带宽依赖 coalescing 效率。ld.shared/st.shared:直接访问片上 SRAM,延迟约 30 cycle,受 bank conflict 影响。tex:经 Texture Unit → Texture Cache → Memory Controller,具备独立的地址计算和过滤管线。ld.const:经 Constant Cache 广播到 warp 所有线程,命中时延迟极低。
同步指令: bar.sync(线程块内屏障)、membar(内存可见性屏障)。bar.sync 由 SM 内部的 barrier 硬件实现:warp 到达 barrier 时设置参与位,所有参与 warp 到达后统一释放。
转换与移动指令: 类型转换(I2F、F2I)、移位、位操作、寄存器间移动。
浮点语义与限制
Tesla CC1.x 的 FP32 运算基于 IEEE 754-1985 的简化实现,存在明确限制:
- Denormal(次正规数)在 G80(CC1.0/1.1)上 flush-to-zero。GT200(CC1.3)可选择保留。
- 除法与平方根通过 RCP/RSQ + Newton-Raphson 迭代实现,舍入模式不可编程。
- 特殊函数精度为近似值(approximate),不保证 IEEE 精度。
整数运算的弱项
Tesla 的整数乘法性能远低于浮点。32-bit 整数乘法(IMUL)在 CC1.0 上需要 16 cycle per warp(4 cycle per instruction,但 dispatch rate 受限),FP32 MAD 仅需 4 cycle。CC1.3 有所改善但仍不及 FP32。为此 NVIDIA 提供 __mul24() intrinsic,利用 24-bit 整数乘法器获得接近 FP32 的吞吐。这一 asymmetry 直接反映在指令选择策略上:编译器倾向于将整数运算转换为浮点,对依赖整数 bit manipulation 的算法(如哈希、加密)构成性能约束。
1.2 芯片级组织
Tesla 的芯片级拓扑采用三级层次:Chip → TPC → SM。
| 层级 | 组成 | 功能 |
|---|---|---|
| Chip | 多个 TPC + ROP Cluster + Memory Controller | 顶层互连,通过 crossbar 连接各 TPC 与 ROP / MC |
| TPC | 2-3 个 SM + 1 个 Texture Unit | 图形与计算的中间聚合单元,Texture Unit 为 TPC 内所有 SM 共享 |
| SM | 8 SP + 2 SFU + Shared Memory / L1 + Register File + Warp Scheduler | 核心计算单元,执行所有 shader / CUDA thread |
| ROP | 光栅操作单元集群 | 负责 alpha blending、depth/stencil test、framebuffer write |
| MC | 内存控制器 | 管理 GDDR3/DDR3 显存访问,每个 MC 对应一个 64-bit 通道 |
G80(GeForce 8800 GTX):8 TPC × 2 SM/TPC = 16 SM,128 SP(16 × 8),核心频率 575 MHz,SP Shader Clock 1.35 GHz。
GT200(GeForce GTX 280):10 TPC × 3 SM/TPC = 30 SM,240 SP(30 × 8),核心频率 602 MHz,SP Shader Clock 1.296 GHz。GT200 将每 TPC 的 SM 数从 2 提升到 3,同时增加了双精度 DP 单元(每 SM 1 个)。
TPC 作为中间层级的设计动机在于纹理采样的共享需求:纹理采样带宽需求高,为每个 SM 配备独立 Texture Unit 在面积上不经济。TPC 内所有 SM 共享一个 Texture Unit,通过 TPC 内部 arbiter 调度访问请求。纹理密集负载下这构成 TPC 内部的结构性瓶颈:当三个 SM 同时密集发射 tex 指令时,Texture Unit 的吞吐成为约束。
1.3 Scheduling
Tesla 的 scheduling 机制是 NVIDIA SM Pipeline 模型的起点。分析它需要先建立一条完整的指令流动路径:
IF → I-Cache → Decode → Warp Scheduler → Scoreboard → Operand Collector → RF Read
→ Dispatch Port → Execution Pipeline → Writeback → Scoreboard Clear
Tesla 的每个 SM 在每周期最多从这条路径上推进一条 warp 指令。以下逐环节解析。
Warp 状态与 Eligibility
每个 SM 维护一个 Warp Pool,G80 最大 24 warps/SM(768 threads),GT200 最大 32 warps/SM(1024 threads)。每个 warp 在任一时刻处于以下状态之一:
- Active: 已分配资源(寄存器、shared memory),等待执行或正在执行。
- Eligible: Scoreboard 判定该 warp 的下一条指令所有操作数就绪,且目标执行单元 / dispatch port 可用。Eligible warp 进入调度器的候选队列。
- Stalled: 操作数未就绪(RAW hazard)、执行单元忙(structural hazard)、或等待 barrier / memory / SFU pipeline。
- Done: 该 warp 的所有线程执行完毕,等待资源释放。
Warp 从 Active 到 Eligible 的转换由 Scoreboard 判定:Scoreboard 维护每个 in-flight 指令的目标寄存器和写回状态,当某 warp 的下一指令的所有源寄存器都标记为"无未完成的写"时,该 warp 变为 Eligible。
Issue Arbitration
Tesla 的 Warp Scheduler 每周期从 Eligible Warp 集合中选择一个发射一条指令。选择策略基于优先级调度而非严格轮询:
- 同一 warp 内连续指令优先(利用 I-Cache locality)。
- 考虑指令类型交错:若上一周期发射了 SP 指令,本周期优先选择可发射 SFU 指令的 warp,以提升 SP 与 SFU pipeline 的并行度。
- 考虑公平性:长期未获发射的 warp 优先级逐步提升,避免 starvation。
硬件代价:Scheduler 需要维护每个 warp 的年龄计数器和指令类型历史,仲裁逻辑须在一个周期内完成。
Scoreboard 机制
Tesla 的 Scoreboard 是 SM Pipeline 中 dependency tracking 的核心。其功能包括:
- RAW Hazard Detection: 当某 warp 的指令 A 写入寄存器 R,在 A 完成 Writeback 前,同一 warp 中任何读取 R 的指令 B 被 Scoreboard 阻塞。
- Structural Hazard Detection: 当目标执行单元(SP/SFU/DP)的所有 pipeline stage 被占满时,后续需要该单元的指令被阻塞。
- Memory Operation Ordering: 同一 warp 内的 LD/ST 指令按程序顺序通过 Scoreboard 保证一致性(Tesla 不要求跨 warp 的 memory ordering)。
Scoreboard 的位宽与 warp 数量、寄存器数量、执行单元数量成正比。G80 的 Scoreboard 需要追踪 24 warps × 每条指令的 3 个源寄存器 + 1 个目标寄存器,硬件面积可观。
Half Warp 执行策略
Tesla 的 32-thread warp 在执行层面被拆分为两个 Half Warp(thread 0-15 和 thread 16-32),每 half warp 占用 2 个 cycle(8 SP × 2 cycle = 16 thread)。因此完整执行一条 warp 指令需要 4 cycle。
Half Warp 划分的硬件含义:
- Register File 访问: RF 被划分为两个 bank group,分别服务两个 half warp,降低单周期读端口需求。
- Memory Coalescing: Coalescing Unit 按 half warp 粒度合并内存请求,16 个线程的地址模式决定一次 memory transaction 的宽度。
- Shared Memory 访问: 16 bank 的 shared memory 与 16-thread half warp 一一对应,理想情况下无 bank conflict。
Half Warp 策略的代价是:warp 指令的完整 latency 比 half warp latency 多一倍,且当线程发散导致一个 half warp 内有效线程数不足 16 时,SP 阵列出现闲置。
线程块分配与全局调度
GigaThread Engine 负责将 Thread Block(CTA)分配到各 SM。分配条件:SM 的剩余资源(warp slot、register file、shared memory)足以容纳整个 thread block。G80 每个 SM 最多 8 thread blocks,GT200 最多 8 thread blocks(但受 warp 上限 32 约束,一个 512-thread 的 block 即占满一个 SM)。
GigaThread Engine 的调度是静态的:thread block 一旦分配到 SM,不会迁移。隐含假设是 thread block 之间无通信、负载均匀,调度器无需考虑动态负载均衡。
分支发散处理
Tesla 处理 warp branch divergence 的硬件路径:
- 条件分支指令到达 Decode,分支单元计算 32 个线程的谓词/条件结果,生成 32-bit Activity Mask。
- 若并非所有线程走同一路径,硬件将当前 PC 和"未走"路径的 Activity Mask 压入 Branch Synchronization Stack。
- 先执行一个路径(如 True 路径)的线程,其余线程被 mask 掉(不执行、不写回)。
- 到达同步点(SSY 指令标记)或路径终点时,从堆栈弹出另一路径的 PC 和 Mask,恢复执行。
- 两路径在汇合点完成后,warp 恢复统一执行。
Branch Synchronization Stack 的深度决定了嵌套分支层数的上限。CC1.x 的堆栈深度为 16 层,对大多数图形 shader 足够,但对深层嵌套的 control flow 可能溢出。
谓词化执行作为分支的轻量替代:编译器将短分支(如单条指令的条件执行)转换为 SETP(设置谓词)+ 谓词化指令,避免压栈开销。谓词化指令仍进入 execution pipeline,但被 mask 掉的线程不写回结果。
1.4 Execution Unit
Tesla SM 的执行单元组织遵循"简单单元 + 高频率 + 高并发"的取向。分析执行单元围绕三个参数:issue slot(每周期可向该单元类型发射的指令数)、pipeline latency(指令从 dispatch 到 writeback 的周期数)、dispatch port(指令从 scheduler 到达 execution unit 的物理路径)。
SP(Streaming Processor / CUDA Core)
每个 SM 含 8 个 SP,每个 SP 是一个标量 FP32/INT32 ALU。
| 参数 | 值 |
|---|---|
| Issue slot per SM | 1 SP instruction per cycle(实际为 1 warp instruction,在 4 cycle 内展开到 8 SP) |
| Pipeline latency | 4 cycle(MAD/ADD) |
| Throughput per SP | 1 FP32 MAD per cycle |
| Peak throughput per SM | 8 FP32 MAD/cycle = 16 FLOP/cycle |
| Supported ops | MAD, ADD, MUL, MIN/MAX, CMP, logic, F2I/I2F |
8 SP 需要在 4 cycle 内完成 32-thread warp 的一条指令,因此每个 SP 在 4 cycle 中处理 4 个 thread 的同一操作。这种时间复用决定了 SP pipeline 的设计:深度为 4 的流水线,每周期接收一组 8 thread(来自当前 active half warp 的 8 个 thread),顺序推进。
SP 的运行频率独立于 SM 其他逻辑:Tesla 采用异步 Shader Clock Domain,SP 运行在 2×~2.4× 核心频率。G80 核心 575 MHz / SP 1.35 GHz。这一设计的动机是用频率弥补标量单元的宽度不足:8 个标量 SP 在 1.35 GHz 下的峰值吞吐相当于 18.7 个运行在 575 MHz 的 SP。
SFU(Special Function Unit)
每个 SM 含 2 个 SFU,负责 transcendental function 和属性插值。
| 参数 | 值 |
|---|---|
| Pipeline latency | 12-16 cycle(RCP/RSQ/SIN/COS) |
| Throughput per SFU | 1 result per cycle |
| Peak throughput per SM | 2 results/cycle |
| Supported ops | RCP, RSQ, SIN, COS, EX2, LG2, attribute interpolation |
SFU 与 SP 共享 warp scheduler 的 issue slot,但走独立的 dispatch port。一个周期内 scheduler 只能选择发射一条 SP 指令或一条 SFU 指令,不能同时发射两者到不同 port(Tesla 的 scheduler 为单 issue)。"粗粒度双发射"效果通过跨 warp 交错达成:warp A 的 SP 指令发射后,scheduler 在下一周期选择 warp B 的 SFU 指令发射,在时间维度上叠合 SP 与 SFU 的利用率。
瓶颈场景:当 kernel 密集使用 __sinf / __powf 等函数时,SFU pipeline 被占满,后续 SFU 指令的 warp 进入 stalled 状态。SP pipeline 空闲也无法弥补 SFU 的吞吐 deficit,这是 Tesla 执行单元异构性的结构性限制。
SFU 的内部实现采用多级查表与泰勒级数组合策略,在面积、精度和 latency 之间取中间解。具体路径:输入操作数的高 8 位用作查表索引,访问一张约 256 行 × 3 列的只读 ROM(三列分别存储 base value、一阶导数、二阶导数)。低 15 位作为 delta 输入,送入 2-3 阶多项式插值单元完成修正。整条路径的 latency 分为两段:ROM 查表约 8 cycle,多项式计算约 4-8 cycle,合计 12-16 cycle,与上表所示硬件参数一致。
权衡逻辑:纯查表方案每增加 1 bit 精度需要 ROM 面积翻倍,FP32 精度下不可接受。纯多项式方案需要多个全精度乘法器并叠加更多 pipeline stage,latency 代价过高。ROM + 泰勒修正的混合路径仅需一张紧凑表加上一个低阶 MAC 树,在 Tesla 的面积预算内即可达到 __sinf/__cosf 所要求的 ULP 精度。
DP(Double Precision Unit,GT200 新增)
GT200(CC1.3)每 SM 增加 1 个 DP 单元,执行 IEEE 754 双精度 FMA。
| 参数 | 值 |
|---|---|
| Pipeline latency | ~32 cycle |
| Throughput per SM | 1 DP FMA per cycle |
| DP:SP peak ratio | 1:8(1 DP unit vs 8 SP units,且 DP 频率更低) |
DP 单元数量稀少的原因:GT200 面向图形市场,双精度仅为满足早期科学计算需求的"点缀"。1:8 的 DP:SP 比率意味着 DP pipeline 100% 占用时,SM 仍有 7/8 的周期可用于 SP/SFU 指令,DP 对吞吐的影响被刻意限制。
1.5 Register File
Tesla 的 Register File 是 SM Pipeline 中操作数供给的核心环节,也是 Occupancy 约束链的关键。
容量与分配粒度
| 参数 | G80(CC1.0/1.1) | GT200(CC1.3) |
|---|---|---|
| RF per SM | 8192 × 32-bit register | 16384 × 32-bit register |
| Allocation granularity | per-thread,编译时确定 | per-thread,编译时确定 |
| Max registers per thread | 128 | 128 |
| Max warps per SM | 24 | 32 |
Register File 的分配发生在 thread block 分配到 SM 时:CUDA 编译器通过 .reg 声明为每个 thread 分配固定数量的寄存器,驱动根据 thread block 的 thread 数和 per-thread register count 计算总需求。若 SM 的 RF 容量不足以容纳 block 的所有 thread,block 被拒绝分配。
静态分配策略的硬件含义:
- 零开销上下文切换: Warp 切换时无需保存/恢复寄存器状态,所有 warp 的寄存器在 RF 中始终驻留。Warp Scheduler 只需切换 active warp ID,RF 根据 warp ID 选择对应寄存器 bank。
- 寄存器碎片: 若编译器为每个 thread 分配 64 registers,一个 256-thread 的 block 需要 16384 registers,恰好占满 GT200 的一个 SM。但一个 192-thread 的 block 仅需 12288 registers,剩余 4096 registers 无法被其他 block 使用(block 级别的分配粒度),形成内部碎片。
Bank Conflict 与 Operand Collector
Register File 采用 multi-bank 组织以支持并发读。Operand Collector 的职责是在指令发射前从 RF 的多个 bank 中收集所有源操作数,解决 bank conflict 造成的读端口竞争。
Operand Collector 的工作流程:
- Warp Scheduler 选中 eligible warp,将该指令的操作数请求发送给 Operand Collector。
- Operand Collector 查询 RF bank 状态:若所需操作数分散在多个 bank 且无冲突,并行读取。若多个操作数位于同一 bank,按序仲裁。
- 操作数全部就绪后,打包发送至对应 Execution Unit 的 input latch。
Tesla 的 Operand Collector 是后续架构 Operand Collector Network 的雏形,但功能相对简单:每个 cycle 服务一个 warp instruction,不支持跨指令的操作数预取。
OC 存在的根本原因是 GPU Register File 的规模与端口数之间的矛盾。为支撑数十 warp 同时驻留,RF 容量可达数十 KB 乃至上百 KB,flip-flop 实现在面积上不可接受,只能选择 SRAM。SRAM 的读端口数量受限于 bitcell 面积,多端口 SRAM 每增加一个端口面积以超线性增长,因此 RF 被切分为多 bank,每个 bank 仅有有限读端口。多条 warp 指令竞争同一 bank 时产生 conflict,OC 作为操作数仲裁缓冲横亘于 issue 与 execution 之间,等待多 bank 响应完毕后再向执行单元输出完整操作数集。
后续架构对这一机制做了两个方向的演化:
调度信息的静态化。 从 Maxwell 开始,编译器在指令编码中嵌入显式 stall counter 与 dependency barrier(即 SCHI 控制字段),将操作数就绪时序在编译期确定。运行期硬件不再需要 OC 动态追踪哪些操作数已从 bank 返回,OC 的核心仲裁逻辑被逐步剥离,其职责被编译器吸收,电路随之简化。Intel 在相似时期亦有 software scoreboard information and synchronization 方向的专利,思路殊途同归。
Operand Reuse Cache。 这是一条独立动机线。即使 bank conflict 已解决,SRAM RF 的读端口延迟仍不可忽视。调度策略倾向对单 warp 连续发射背靠背指令时,相邻指令频繁回访相同寄存器,每次都穿透到 RF 则累积可观延迟。解决方式是在操作数通路放一小块以 flip-flop 构成的寄存器缓存(容量极小,通常 per-source-operand 仅 1 entry),编译器在指令中标注 reuse flag 控制命中与替换。Reuse Cache 与 OC 在数据通路上位置相近,但动机不同:前者缓解端口延迟,后者仲裁 bank 竞争。
Occupancy 约束链
Occupancy(实际驻留 warp 数 / 最大驻留 warp 数)受三条约束链的交集限制:
约束 1 — Warp Slot: SM 最多容纳 24(G80)或 32(GT200)个 warp,与寄存器/共享内存无关。
约束 2 — Register File: 设编译器为每个 thread 分配 R 个寄存器,block 含 T 个 thread,SM 的 RF 容量为 C。则每个 SM 可容纳的 block 数受限于 C / (R × T)。
约束 3 — Shared Memory: 设 block 使用 S byte shared memory,SM 的 Shared Memory 容量为 M(16 KB),则 SM 可容纳的 block 数受限于 M / S。
三条约束同时满足时 Occupancy 最高。任一约束触顶即成为瓶颈。例如:
- 一个 thread 使用 64 registers 的 kernel,在 256-thread block 下,GT200 的 16384 registers 恰好容纳 1 个 block(32 warp),此时 warp slot 约束未触顶(32/32),RF 约束触顶。
- 若 block 缩小到 128 thread,RF 可容纳 2 个 block(32 warp),但 G80 的 thread block 上限(8 blocks)和 warp 上限(24 warps)可能先触顶。
Occupancy 的下降直接削弱延迟隐藏能力:更少的驻留 warp 意味着当 active warp 因 memory/cache/SFU stall 时,scheduler 可切换到的 eligible warp 减少,执行单元 idle cycle 增加。
Shared Memory
Tesla 的 Shared Memory 是 16 KB 片上 SRAM,被组织为 16 bank,每 bank 宽度 32-bit。Half warp(16 thread)的访问模式与 16 bank 一一对应时达到最大带宽。若多个 thread 访问同一 bank 的不同地址,产生 bank conflict,访问被串行化。最坏的 16-way conflict 下,16 个 thread 需要 16 个 cycle 完成访问。
Shared Memory 与 Texture Cache 在 G80 上复用同一块 SRAM,可在 driver 配置下切换比例。这种共享的代价是:启用更多 Shared Memory 时 Texture Cache 容量减少,纹理密集 kernel 的 cache hit rate 可能下降。
1.6 Memory Subsystem
Tesla 的 Memory Subsystem 由三条分离的访存通路构成,各自服务不同类型的内存操作,在 Memory Controller 处汇合,竞争访问外部 GDDR。
Compute LD/ST Path
全局内存的 load/store 通路是 Tesla 最薄弱的环节:CC1.x 没有通用 L1 Data Cache,所有全局内存 LD/ST 直接由 Memory Coalescing Unit 处理后送往 Memory Controller。
Memory Coalescing 的硬件机制:
- LD/ST Unit 按 half warp(16 thread)收集内存请求,每个 thread 提交一个 32-bit 地址。
- Coalescing Unit 检查 16 个地址是否落在连续的 64-byte(16 × 4B)对齐区间内。若是,合并为一次 64-byte memory transaction。
- CC1.0/1.1 要求地址严格连续且对齐到 64-byte boundary。若任一 thread 的地址偏离,coalescing 失败,请求退化为最多 16 次独立的 4-byte 访问。
- CC1.3(GT200)放宽约束:只要 16 个地址落在同一个 128-byte cache line 内,即可合并为一次或两次 64-byte transaction,允许非连续访问(strided access)。
缺少通用 L1 Data Cache 的开发者可见症状:
- 全局内存访问延迟固定为 400-600 cycle,无法通过数据复用降低(除非显式使用 Shared Memory)。
- 访问模式不规则(scatter/gather)时,coalescing 效率急剧下降,有效带宽利用率可能低于 10%。
- 同一个 warp 对同一地址的多次读取每次都要访问 DRAM,无法自动从 cache 服务。
Cacheline 宽度与 Coalescer 行为:
CC1.3 引入的 128-byte cache line 并非任意选取,一个 Warp 32 条线程各访问 4B(一个 32-bit 寄存器宽度的字),连续排列后恰好 128 byte。从 Kepler 起,128B cacheline 成为 GPU 内存子系统的基本传输粒度,这一点 microbenchmark 可以直接验证。
后续架构对 coalescing 的实现进一步细化到 sector 粒度。以 Turing 为例,128B cacheline 被划分为 4 个 32B sector,每个 sector 对应 8 条线程的访问。Coalescer 以 sector 为最小合并单位而非整条 cacheline:即使 32 条线程访问完全相同的地址,硬件仍发出 4 个独立的 32B sector 读请求(每 8 线程一组触发一次),而非合并为单次 128B 请求。这是实测跑出来的行为,揭示了 coalescer 内部按 8-thread 分组的流水线结构。
Sector 粒度同样影响 eviction 行为:一条 128B cacheline 被驱逐时,仅 dirty sector 需要写回,未被修改的 sector 可以静默丢弃,减少了写回带宽消耗(microbenchmark 实测可确认这一点)。替换策略并非经典 LRU,在 4-way set associative 的结构中,microbenchmark 实测显示 way2 被替换的概率高于其他 way,暗示硬件采用了某种 pseudo-LRU 或加权随机策略。
Texture Sampling Path
纹理通路独立于 LD/ST 通路,拥有自己的地址计算、缓存和过滤管线:
| 组件 | 功能 |
|---|---|
| Texture Address Unit | 将纹理坐标(u, v)转换为内存地址,处理 wrapping/clamping/border mode |
| Texture Cache | 每 TPC 一个,缓存最近访问的纹理数据,2D spatial locality 优化 |
| Texture Filter Unit | 双线性/三线性/各向异性过滤,每周期处理 4 pixels |
纹理通路的延迟约 200-300 cycle,低于全局内存 LD 的主要原因是有 Texture Cache。但 Texture Cache 仅对纹理访问有效,compute LD 无法使用。
Shared Memory Path
Shared Memory 通路是片上的低延迟通路, latency ~30 cycle,无 coalescing 需求(因为数据已在片上),受 bank conflict 约束。Shared Memory 的设计定位是"由软件管理的 L1 cache":开发者通过 __shared__ 声明和显式的 ld.shared / st.shared 指令管理数据驻留与替换,硬件不提供自动缓存机制。
三条通路的关系:一个 SM 内的 warp 可以同时有 in-flight 的 global LD(经 Coalescing Unit)、shared LD(经 Shared Memory)和 tex 指令(经 Texture Unit),这些通路在 Execution Pipeline 的 dispatch stage 竞争 issue slot,在 Memory Controller 处竞争 DRAM bandwidth。
Memory Consistency 与 Atomic
Tesla 采用 Weak Consistency Memory Model:
- 同一 warp 内的内存操作按程序顺序执行(由 Scoreboard 保证)。
- 同一 thread block 内不同 warp 的内存操作顺序无保证,需要
bar.sync+membar显式同步。 - 不同 thread block 的内存操作顺序无保证,CUDA 不保证跨 block 的通信。
- Constant Cache 和 Texture Cache 无硬件一致性:写入全局内存后,已缓存的纹理/常量数据不自动失效。
Atomic Operations(CC1.1+):atomicAdd、atomicMin 等指令由 Memory Controller 处的硬件 atomic unit 实现,执行 read-modify-write 原子操作。Atomic 操作的吞吐远低于普通 LD/ST:当多个 SM 同时 atomic 到同一地址时,serialize 在 Memory Controller 处,形成热点瓶颈。
1.7 Function Features
统一着色器硬件路径
Tesla 统一着色架构的硬件含义:SM 阵列通过 GigaThread Engine 的动态分配,执行顶点着色、几何着色、像素着色三种程序,不再区分专门的 VS/PS 硬件。
Unified Shader 的数据通路:
- 几何阶段: Primitive 经 PolyMorph Engine(Tesla 中集成在固定功能管线)转换后,以顶点 thread block 的形式分发到 SM,执行 vertex shader。
- Geometry Shader 阶段(DirectX 10): Vertex shader 输出的 primitive 经 primitive assembly 后,以 geometry thread block 分发到 SM,执行 geometry shader。Geometry Shader 的输出(可能生成 0 到多个新 primitive)经 stream output 写入 buffer 或继续进入光栅化。
- 像素阶段: 光栅化后的像素 quad(2×2 pixels)被打包为 warp(8 quads = 32 pixels),分发到 SM 执行 pixel shader。
统一架构对 SM scheduling 的影响:三种 shader 阶段共享同一套 warp pool 和 scheduler,但资源需求 pattern 不同。Vertex shader 通常 register pressure 低但控制流复杂。pixel shader 通常 register pressure 高、纹理访问密集,且存在大量 short warp(边缘像素导致 warp 内有效线程不足)。GigaThread Engine 的 block 分配不区分阶段,SM scheduler 也不做阶段感知,统一性的代价是某些 stage-specific 的优化无法实施。
DirectX 10 硬件能力
Tesla 对 DirectX 10 / Shader Model 4.0 的支持映射到以下硬件能力:
- Geometry Shader: 每 SM 可执行 geometry shader 程序,通过 stream output 将结果写回内存。硬件支持 GS 的 emit/cut 操作。
- 状态无关纹理采样: Texture 绑定不再受限于固定-stage 的 sampler 数量,shader 中可动态索引 texture/sampler。
- 整数指令支持: Shader Model 4.0 要求完整的 32-bit 整数运算,Tesla 的 INT32 ALU 满足该要求(尽管性能弱于 FP32)。
- 更大的寄存器空间与指令长度: Shader 可访问最多 128 registers,指令长度扩展至 64-bit(Shader Model 3 为 32-bit)。
CUDA 硬件-软件契约
CUDA 编程模型与 Tesla 硬件之间的契约边界定义了开发者可以依赖什么、不能依赖什么:
硬件保证(开发者可依赖):
- SIMT 执行:32 thread warp 内的指令同步执行,barrier 保证 block 内 warp 同步。
- 零开销 warp 切换:Scheduler 可在任意 cycle 切换 warp,无需软件干预。
- Shared Memory:16 KB 片上 SRAM,同 block 内线程可通过
__syncthreads()协调访问。 - 全局内存原子操作(CC1.1+):同一地址的原子操作保证原子性。
硬件不保证(开发者不可依赖):
- Warp 内的 thread 执行顺序:虽然 warp 同步执行指令,但 memory operation 的 completion order 不保证。
- Thread block 到 SM 的映射:GigaThread Engine 的分配策略不透明。
- Cache 的存在与容量:CC1.x 无通用 L1 cache,依赖 cache 的优化策略可能失效。
- 浮点精度细节:Denormal 处理、特殊函数精度均为近似值。
实际约束:CUDA 程序的正确性必须建立在不依赖 warp 内 thread 执行顺序和不依赖 cache 的前提下。任何超出此边界的假设(如 warp 内 implicit synchronization)属于未定义行为。
1.8 小结
设计哲学
Tesla 的核心赌注:只要并发度足够高,调度开销(warp switch、branch divergence serialization、scoreboard tracking)可以被足够多的并行线程掩盖,通用 SM 在平均利用率上得以超越专用硬件。标量 ISA + SIMT 把并行管理从软件推给硬件,16384 registers/SM 使 32 warps 全部上下文同时驻留实现零开销切换,软件管理的 Shared Memory 以可预测延迟和明确容量控制换取 L1 Cache 的自动化。
关键权衡
| 权衡 | 选择 | 代价 |
|---|---|---|
| 标量 SP vs 向量 SIMD | 8 个标量 SP + Shader Clock 倍频 | 单指令吞吐低于宽向量单元,依赖高频弥补 |
| 软件 Shared Memory vs 硬件 L1 Cache | 16 KB 可编程 SRAM,无自动缓存 | 程序员必须显式管理数据移动,不规则复用模式无法自动优化 |
| 统一 Shader vs 专用阶段硬件 | 同构 SM 阵列覆盖所有阶段 | 阶段特定优化缺失,vertex/pixel/geometry 竞争同一资源池 |
| 高 FP32 吞吐 vs 整数/DP 能力 | FP32 MAD 4 cycle / IMUL 16 cycle / DP 32 cycle | 整数密集型算法性能受限,科学计算 DP 需求无法满足 |
| 单 Issue Scheduler vs 双 Issue | 每周期 1 条 warp 指令 | SP 与 SFU 无法同周期发射,依赖 warp 交错实现并行 |
遗留痛点
Tesla 的以下限制直接驱动了后续演进:通用 L1 Data Cache 缺失使不规则访问模式带宽利用率极低(Fermi 引入 L1 Cache 回应);Warp Scheduler 单 Issue 限制了 SP/SFU 并行度;全局内存 Coalescing 过于严格(CC1.0/1.1 要求地址严格连续对齐);DP 峰值仅为 SP 的 1/8(Fermi 提升至 1/2);Branch Synchronization Stack 串行化导致分支密集代码 warp utilization 下降;编译时静态确定的 per-thread register count 在运行时无法调整,微小增加即可能触发 Occupancy 断崖式下降。
二、Fermi (2010)
Fermi 核心芯片代号 GF100,是 NVIDIA GPU 架构的一次关键迭代。Tesla(G80/GT200)建立了标量 ISA、SIMT 执行模型、Warp 级调度、分支堆栈和片上 Shared Memory 的框架,但设计始终围绕图形渲染展开,通用计算是附加能力,不是架构设计的主要驱动。Fermi 出发点不同:它将 GPU 重新定位为"通用并行处理器",图形能力成为子集而非主导。转变体现在 ISA 的通用化、缓存层次的完整化、内存一致性的引入,以及 DP 浮点吞吐的提升上。
GF100 完整芯片包含 4 个 GPC(Graphics Processing Cluster),每个 GPC 含 4 个 SM,全芯片 16 个 SM、512 个 CUDA Core。产品线分为消费级 GeForce(GF100/GTX 480、GF104/GTX 460)与数据中心 Tesla(GF100/Tesla C2050/C2070)。两者核心架构相同,但双精度单元数量、ECC 支持、功耗预算和 binning 策略有差异,后文分别说明。
2.1 ISA
Fermi 对齐到 PTX 2.0(Compute Capability 2.0)。Fermi 的 ISA 变革涉及三个层次:CUDA Feature 定义编程模型能力边界(如 UVA、原子操作、L1/L2 Cache 的可见性)。PTX 是虚拟 ISA,提供跨代兼容的中间表示,编译器将 CUDA C/C++ 生成 PTX。SASS 是硬件实际执行的原生指令,由 PTXAS(PTX Assembler)在编译后期或驱动 JIT 阶段生成,包含针对特定微架构的寄存器分配、指令调度和调度控制信息。同一 PTX 在不同代 GPU 上可生成不同 SASS,这是 NVIDIA "一次编译、多处运行"的技术基础,也意味着 SASS 才是直接控制流水线行为的最终接口。
FMA 与 MAD:精度差异的执行单元根源
Fermi 用硬件 FMA(Fused Multiply-Add)指令替代了 Tesla 时代的 MAD(Multiply-Add)。MAD 执行 A×B+C 时经历两次舍入:乘法结果舍入到 SP 精度,再与 C 相加后第二次舍入。FMA 将乘加合并为单一操作,仅在最终结果输出时做一次舍入。区别在于:FMA 的乘法器输出保留完整保护位(guard/round/sticky bits),直接进入加法器,中间结果不截断。对大规模点积、矩阵乘法、迭代求解器等累加密集型算法,这有数值稳定性收益,累积误差从 O(n×ulp) 量级降低到接近 O(ulp) 量级。
从执行单元角度看,FMA 指令占用 CUDA Core 的 FPU Pipeline 一个完整周期。Tesla 的 MAD 虽然也是单周期吞吐,但精度代价已在上述路径中说明。FMA 的引入同时扩展了双精度能力,这是 Fermi 面向 HPC 的关键设计决策。
完整 32 位整数指令集
Tesla 架构支持 24 位整数乘法(MUL24),这是图形纹理坐标计算的遗留优化:24 位乘法器面积小、延迟低,但对通用算法是功能缺陷。Fermi 在每个 CUDA Core 内部集成了一个完整的 32 位 ALU,支持与、或、异或、位移(左移/右移/算术右移),以及完整的 32 位乘法和乘法-累加。MUL24 指令在 Fermi 上仍可执行,但不再享受面积优势带来的性能收益,因为底层硬件已替换为 32 位通路。密码学、哈希计算、压缩算法、精确索引运算等 workloads 由此可直接在 GPU 上运行,无需拆分多位运算到多条指令。
IEEE 754-2008 合规性
Fermi 之前的 GPU 架构对特殊浮点值采取实用主义处理:Subnormal/Denormal Number 被 Flush-to-Zero(FTZ),NaN 的传播规则不严格,舍入模式仅支持 nearest-even。Fermi 的 FPU 增加了对 Subnormal 的完整处理路径:当指数域全零且尾数非零时,不再强制清零,而是按 IEEE 754-2008 规定的 subnormal 格式正常计算。Fermi 还支持 directed rounding(向正无穷、负无穷、零方向舍入),这是某些数值算法(如区间算术)的必要条件。
硬件代价是 FPU 的 normalize/denormalize 逻辑面积增加,Subnormal 处理的延迟路径比正常浮点数更长。Fermi 提供了控制寄存器位(通过 PTX/SASS 的 FTZ 标志)允许在不需要 subnormal 的场景下回退到 flush-to-zero 模式,以换取吞吐。
新指令:Vote、同步与函数调用
PTX 2.0 引入 vote.ballot 和 vote.all / vote.any,允许一个 Warp 内 32 个线程就布尔条件做硬件级投票,vote.ballot 返回 32 位掩码表示各线程的判断结果。这取代了 Tesla 时代通过 Shared Memory 跨线程通信的低效方案,Stream Compaction 和 Warp-level reduction 可在 2-3 个指令周期内完成分支路径的线程掩码分析。Fermi 还增加了递归函数调用和返回指令的直接硬件支持(call/ret),调用栈保存在片上存储中,不再依赖编译器内联所有函数。这对模块化编程有必要性,但递归深度受限于栈空间,过深的调用链会导致栈溢出到 Local Memory。
2.2 Scheduling
Tesla 架构每个 SM 配备单个 Warp Scheduler,每周期从驻留 Warp 中选取一个满足发射条件的 warp,发射 1 条指令。一个 Warp 的 32 个线程需要 4 个周期才能遍历全部执行 lane(4-cycle issue granularity),单个 warp 无法在一个周期内填满 SM 的全部 8 个 SP。scheduler 要么发射算术指令占用 SP,要么发射访存指令占用 LD/ST,两者难以重叠。唯一的发射 slot 被长延迟指令(如全局内存 load)占据时,后续 ready 的 warp 即使执行单元空闲也必须等待,造成结构性浪费。
Dual Warp Scheduler 的硬件结构
Fermi 每个 SM 配置两个独立的 Warp Scheduler(Warp Scheduler 0 和 Warp Scheduler 1),各自拥有独立的发射槽(Issue Slot)和分发逻辑。每个 scheduler 管理自己管辖的 warp subset。GF100 每个 SM 最多驻留 48 个 warp(1536 线程),两个 scheduler 各负责其中约 24 个 warp 的调度。每个时钟周期(Hot Clock,即 2×Core Clock),两个 scheduler 同时检查各自 warp pool 中的 eligible warp,各自发射 1 条指令,总计每周期最多 2 条指令发射。
关键约束:Dual-Issue 不是无条件的。两个 scheduler 发射的指令必须目标执行单元不冲突。例如 Scheduler 0 发射 FMA 指令占用 Execution Cluster 0 的 16 个 CUDA Core,Scheduler 1 可以同时发射 LD/ST 指令占用 LD/ST Unit,或发射 SFU 指令,但不能在同一周期向同一组 16 个 CUDA Core 分发两条指令。Fermi 将 32 个 CUDA Core 物理划分为两个 16-lane 执行块(Execution Cluster),每个 scheduler 默认向其中一个 cluster 分发算术指令。这种硬分区简化了仲裁逻辑,但理想的 Dual-Issue 场景要求两个 warp 的指令类型互补(如一个算术 + 一个访存,或一个算术 + 一个 SFU)。
执行资源分区与仲裁
SM 内部的执行单元在两个 scheduler 间的分配如下:
- 32 个 CUDA Core → 均分为两个 16-lane cluster,分别服务两个 scheduler
- 16 个 LD/ST Unit → 由两个 scheduler 共享,但需要仲裁避免端口冲突
- 4 个 SFU → 共享资源,32 线程的 SFU 指令需要 8 个周期完成(每周期 4 线程)
- 16 个 DP FMA Unit → 共享资源,位于 SM 的双精度执行块中
当一个 scheduler 需要访问非独占资源(如 LD/ST、SFU、DP Unit)时,须经过仲裁器(Arbiter)的许可。仲裁策略未公开,但典型的 round-robin 或优先级轮转机制确保两个 scheduler 不会同时占用同一组执行单元。即使两个 warp 都处于 ready 状态,如果都需要 LD/ST,第二条指令会被 stall 一个周期。
Scoreboard 的工作方式
Fermi 的 Scoreboard 延续 Tesla 的机制:记录已发射但未写回的指令目标寄存器,源操作数与 pending 写冲突时该 warp 被标记为 not eligible。差异在于每个 scheduler 独立维护自己的 Scoreboard 视图(或分区访问同一全局 Scoreboard,微架构细节未公开)。
双调度器场景下 Scoreboard 的复杂度增加:两条来自不同 scheduler 的指令可能写入同一寄存器(WAW 依赖),或一条指令读取另一条正在写入的寄存器(RAW 依赖)。硬件须确保 Write-after-Write 和 Read-after-Write 的正确性。Scoreboard 在 Writeback 阶段清除对应条目,warp 恢复 eligible 状态。
可观察症状
- 若 kernel 仅含算术指令而无访存指令,Dual Warp Scheduler 的优势难以发挥,两个 scheduler 竞争同一类资源,实际 issue rate 接近单 scheduler 的 1.2-1.5×,而非理想的 2×
- 若 warp 内存在频繁的分支发散(divergence),有效 eligible warp 数量减少,scheduler 选择空间缩小,执行单元利用率下降
nvprof/ Nsight Compute 中warp_scheduler_eligible和issue_slot_utilization指标可量化调度效率
2.3 Execution Unit
CUDA Core 的内部结构
Fermi 的 CUDA Core 是标量执行单元,每个 Core 包含一个 FPU(浮点管线)和一个 ALU(整数管线)。关键细节:FPU 和 ALU 共享同一个 Dispatch Port,每个周期只能接收一条指令,要么浮点要么整数,不能同时执行。编译器通过指令调度在浮点和整数指令间穿插,隐藏端口共享的约束。FPU 支持 SP FMA、SP 乘、SP 加、类型转换。ALU 支持 32 位整数加减乘、位运算、比较、地址计算。
双精度 FMA 与 SKU 差异
Fermi 每个 SM 集成 16 个 DP FMA Unit,峰值 DP 吞吐为 SP 吞吐的一半(GF100 全芯片 512 SP Core @ Hot Clock,256 DP Unit 的理论峰值比为 1:2)。这是 Tesla 架构(GT200 DP:SP = 1:8)的 4 倍提升。
但 1:2 的比例仅在完整 GF100 芯片的数据中心 SKU(Tesla C2050/C2070)上实现。消费级 GeForce GTX 480 虽使用同一 GF100 die,NVIDIA 通过熔断或软件限制将 DP 性能锁死在 SP 的 1/8,强制区分产品线。后续 GF104(GTX 460)采用不同 SM 配置,每个 SM 仅保留 8 个 DP Unit,DP:SP 降至 1:12,进一步拉开消费级与计算级的 DP 能力差距。
SFU 翻倍与吞吐提升
Tesla 每个 SM 配备 2 个 SFU,一条 Warp(32 线程)的超越函数指令(sin/cos/rsqrt/rcp)需要 16 个周期完成(每周期 2 线程,双发射到 SFU)。Fermi 将 SFU 增加到 4 个,同一 warp 的 SFU 指令吞吐缩短到 8 个周期。SFU 的 latency 约为 4-7 周期(取决于具体函数),高于 CUDA Core 的 FMA latency(约 4 周期),编译器需避免 SFU 指令后的 immediate RAW 依赖导致 scheduler stall。
Hot Clock 的代价与收益
自 G80 引入的 Hot Clock(Shader Clock = 2× Core Clock)在 Fermi 延续。GF100 的 Core Clock 约 700 MHz,Hot Clock 为 1.4 GHz,CUDA Core、Warp Scheduler、Register File 访问等核心逻辑在此频率下运行。非 SM 组件(ROP、Memory Controller、L2 Cache、PCIe 接口)运行在 Core Clock。异步时钟域设计的收益:计算密集型 kernel 的 ALU 吞吐随 Hot Clock 线性放大。代价有三:(1) 跨时钟域同步的 FIFO 开销。(2) SM 功耗密度集中,成为散热瓶颈,GF100 的 TDP 达到 250W,SM 动态功耗占主导。(3) 后续 Kepler 架构放弃 Hot Clock 统一为单一时钟域,说明此设计在先进工艺下收益递减。
2.4 Register File
Fermi 每个 SM 的 Register File 容量从 Tesla(GT200)的 16K 个 32 位寄存器(64 KB)增加到 32K 个(128 KB)。翻倍直接对应 SM 内 CUDA Core 数量从 8 增加到 32。四倍执行单元增长伴随两倍寄存器增长,寄存器带宽和容量的压力实际增大了。
硬件组织与访问方式
Register File 是划分 bank 的多端口 SRAM 结构。32 个 CUDA Core 每周期可能同时读取最多 64 个源操作数(2 操作数 × 32 thread),需要极高的读端口带宽。Fermi 通过 Operand Collector 架构缓解端口竞争:指令在 Decode 阶段将被拆分为多条 sub-instruction(对应 4 个执行周期),每个 sub-instruction 只需读取 8 个线程的操作数,降低瞬时端口压力。Operand Collector 缓存已读取的寄存器值,避免同一 warp 连续指令的重复 RF 访问。
每线程 63 寄存器限制
Fermi 每线程最多可分配 63 个寄存器(实际可用 1-63,0 号寄存器恒为零)。这不是任意设计:warp 调度器使用 6 位编码标识寄存器编号(2^6 = 64),63 是可用上限。编译器(NVCC/PTXAS)的寄存器分配器判定某线程需要超过 63 个 live variables 时,必须将部分变量溢出(spill)到 Local Memory。
Register Spilling 机制
溢出变量被分配到线程私有的 Local Memory 区域,物理上位于片外 DRAM,访问路径经过 L1 Cache 和 L2 Cache。一次 Local Memory load 的延迟约为 400-800 周期(取决于 cache 命中情况),对比 Register File 读延迟(0 周期,与调度流水线重叠),spilling 开销极高。编译器尝试将溢出数据布局到连续地址以促成 cache line 合并访问,但 spilling 仍严重损害性能。
开发者可通过 __launch_bounds__ 或 --maxrregcount 限制每线程寄存器用量,促使编译器使用 Shared Memory 缓存中间数据或重新计算而非 spill。Nsight Compute 的 launch__registers_per_thread 和 sass__spilled_registers 指标可监控 spilling 情况。
可观察症状
- Occupancy(实际驻留 warp / 48 warp 上限)低于预期时,先检查寄存器用量:一个 Thread Block 若含 1024 线程、每线程 63 寄存器,总需求 64512 寄存器,接近 32K 上限(两个 block 即超限),只能驻留 1 个 block,occupancy 被锁死
- 每线程使用 32 寄存器时,1536 线程(48 warp)总需求 49152,在 32K 限制内,可达 100% occupancy。寄存器用量与 occupancy 的关系是线性的
2.5 Memory Subsystem
Fermi 之前的 GPU 没有通用 Cache Hierarchy:Tesla 依赖程序员显式管理 Shared Memory 和 Texture Cache 来优化数据访问,全局内存访问直连 DRAM,无自动缓存。Fermi 引入了完整的 Cache Hierarchy,将 GPU 内存子系统从"显式管理为主"转向"硬件自动缓存 + 显式优化并存"。
L1 Cache / Shared Memory 的可配置分割
每个 SM 内部集成 64 KB 片上 SRAM,可通过运行时 API(cudaFuncSetCacheConfig)配置为两种模式:
- 48 KB Shared Memory + 16 KB L1 Cache
- 16 KB Shared Memory + 48 KB L1 Cache
硬件实现上,这 64 KB SRAM 被划分为多个 bank,通过地址解码逻辑选择访问路径。Shared Memory 路径提供 programmer-managed 的低延迟(约 20-30 周期)数据交换,用于 Thread Block 内线程协作。L1 Cache 路径提供对 Global Memory 和 Local Memory 的自动缓存。二者互斥占用同一块物理 SRAM:选择 48 KB Shared 意味着 L1 容量压缩到 16 KB,cache line 数量减少,Global Memory load 的 hit rate 下降。选择 48 KB L1 则 Shared Memory 可分配空间减半,影响需要大块共享数据协作的算法。
配置决策的依据是 workload 的访存特征:以规则、可预测、数据重用的访存为主的 kernel(如 stencil 计算)受益于大 L1。以线程间数据交换和生产者-消费者模式为主的 kernel(如 reduction、transpose)受益于大 Shared Memory。该配置以 kernel 为单位,在不同 kernel launch 间动态切换。
Unified L2 Cache 的角色
GF100 芯片集成 768 KB Unified L2 Cache,位于所有 SM 和 DRAM Controller 之间。Unified 的含义是 L2 服务所有类型的内存请求:Global Memory LD/ST、Texture 采样、Constant 读取、原子操作,以及跨 SM 的数据通信。L2 Cache 是 SM 访问片外 DRAM 的必经之路,所有内存请求(无论是否命中 L1)都会经过 L2。统一设计取代了 Tesla 时代分离的 Texture Cache 和 ROP 内存路径,简化了 coherence 逻辑。
L2 Cache 的关键角色:
- 流量聚合:16 个 SM 的内存请求在 L2 汇聚,通过行缓冲(row buffer)命中减少 DRAM 激活次数,有效放大内存带宽
- SM 间通信:当 SM_A 写入 Global Memory 地址 X,SM_B 读取同一地址时,数据经 L2 中转,无需往返 DRAM,构成 GPU 上最基础的跨 SM 数据共享机制(latency 约 100-200 周期)
- 原子操作加速:Fermi 的 32 位整数原子操作在 L2 Cache 层面以 Read-Modify-Write 方式完成,对比 Tesla 必须直达 DRAM,latency 降低一个数量级
多条并行的内存数据路径
Fermi 的内存子系统维持多条并行的数据路径,服务于不同的访存语义:
| 路径 | 起点 | 缓存层次 | 用途 |
|---|---|---|---|
| Global LD/ST | SM LD/ST Unit | L1 → L2 → DRAM | 通用读写,合并访问 |
| Texture/Constant | SM Texture Unit | L1/TEX → L2 → DRAM | 只读,带专用插值/过滤硬件 |
| Local Memory | SM LD/ST Unit | L1 → L2 → DRAM | 寄存器溢出、栈变量(私有) |
Constant Memory 路径在 Fermi 上仍保留专用的 Constant Cache(8 KB per SM),用于存储 kernel 参数和编译期常量。Texture 路径通过 L1/TEX Cache(与 Shared/L1 物理分离),支持 1D/2D/3D 纹理采样和硬件插值。多条路径意味着:同一个 kernel 中混用 Global LD/ST 和 Texture 采样不会争夺 L1 Cache 资源,因为它们走不同的 cache 层次。
Coalescing 机制的改进
Tesla 的 coalescing 要求 Warp 内线程访问的地址严格连续且对齐到 64B 边界,才能合并为单次内存事务。Fermi 放宽了约束:只要 Warp 内线程访问的地址落在同一个 128B cache line 内(或跨相邻 line),即使不完全连续,也能合并为一次或两次 L1 cache access。改进依赖 L1 Cache 的 line buffer 和 memory controller 的地址聚类逻辑,降低了对齐要求,不规则但空间局部性良好的访存模式因此受益。
非阻塞 L1 与 MSHR
Fermi 的 L1 Cache 是非阻塞设计(non-blocking cache),其核心硬件结构为 MSHR(Miss Status Holding Register)。当一次 coalesced memory request 在 L1 中 miss 时,硬件分配一个 MSHR entry 记录该请求的状态,包括发起线程的 ID 集合与各自的 byte offset。L1 不会因为一次 miss 而阻塞后续访存请求。在等待 L2 返回数据期间,后续 miss 可继续分配新的 MSHR entry,多条 outstanding request 并行推进。L2 响应到达时携带对应的 MSHR entry ID,硬件据此将数据回填到正确的线程寄存器并释放该 entry。
单个 MSHR entry 还支持请求合并:若多次 miss 落在同一 cache line,后续请求合并到已存在的 entry 中,不消耗新条目。microbenchmark 实测显示 Fermi 每 SM 约 128 个 MSHR entry,每个 entry 可合并最多 8 个请求。L1 可同时追踪 128 条独立的 outstanding cache line miss。
MSHR 的容量直接限制了访存并发度。当 64 个活跃线程各自发出 2 条独立 load 指令(共 128 个 coalesced miss)时,若这些请求全部 miss 且地址不重叠,MSHR entry 恰好耗尽。超出该点后,新的 miss 必须等待 entry 释放。跑 benchmark 能清楚看到访存延迟出现突变,从流水线隐藏的正常值跳升到 stall-dominated 的数倍水平。优化 Fermi 访存并发时,除关注 bandwidth 和 cache hit rate 外,还需确保 outstanding miss 数不超过 MSHR 容量。
ECC 支持(数据中心 SKU)
Tesla C2050/C2070 支持全路径 ECC:Register File、Shared Memory、L1/L2 Cache、DRAM 均配置 SECDED(Single Error Correction, Double Error Detection)编码。ECC 增加的存储开销为 12.5%(64 bit data + 8 bit ECC),DRAM 有效带宽相应下降。ECC 的编码/解码逻辑在内存控制器内完成,对软件透明,但校验失败会触发不可纠正错误(UE)中断。消费级 GeForce 不支持 ECC。
2.6 Function Feature
PolyMorph Engine 与硬件 Tessellation
DirectX 11 引入 Hull Shader、Tessellator 和 Domain Shader 三阶段的 hardware tessellation 管线。Fermi 在每个 SM 内部集成 PolyMorph Engine,负责:
- 顶点拾取(Vertex Fetching)
- Tessellation 控制点计算(Hull Shader 输出)
- 细分阶段(Tessellator:根据细分因子生成新顶点和三角形)
- 顶点属性插值(Domain Shader 执行前的属性设置)
- 视口变换(Viewport Transform)
PolyMorph Engine 是固定功能硬件(非可编程 shader),与 SM 的可编程 execution unit 并行工作。Tessellation 的几何放大倍数由 Hull Shader 的 tessellation factor 动态决定,一个低多边形模型可被实时细分成数千个三角形。PolyMorph Engine 每 SM 一个的设计确保 tessellation 吞吐随 SM 数量线性扩展,但极端细分场景(tessellation factor 达到 64)仍可能令 PolyMorph Engine 成为瓶颈,几何输出速率超过 rasterization 和 pixel shading 的处理能力。
Tessellator 固定电路微架构
PolyMorph Engine 中的 Tessellator 本身是一组纯组合/时序逻辑,不执行可编程指令。其内部由三个流水级构成:
- Calc:接收 Hull Shader 输出的外边(outer edge)TF 与内边(inner edge)TF,执行归一化,将浮点 TF 按 partitioning 模式取整(integer/pow2 模式直接截断,fractional odd/even 模式保留小数部分以实现平滑过渡,但 parity 在 patch 生命周期内固定)。归一化后计算每段的步长 k 和偏移 delta,写入内部寄存器供后续级消费。
- Sampling:根据参数域类型(Quad / Triangle / Isoline)在归一化坐标系内遍历各段,按 k/delta 插值生成新顶点的 (u, v) 坐标。Quad 域沿两轴独立采样后做外积,Triangle 域使用重心坐标递归内缩,Isoline 域只需单轴线性采样。该级的输出是一组无连接关系的裸坐标点。
- Stitching:将 Sampling 级产出的点连接成三角形。常规区域(同一边上 TF 一致)使用梯形缝合,内外环顶点交替连接。过渡区域(相邻边 TF 不一致)采用二叉树中序遍历确定顶点连接顺序,保证细分结果在不同 TF 交界处无裂缝(crack-free)。最终输出 index buffer 形式的三角形列表,送入 Domain Shader 阶段。
三级流水的延迟固定且可预测,但吞吐受 TF 值支配:TF=2 时每 patch 仅产出数个三角形,TF=64 时单 patch 可膨胀至数千个三角形。这种数据放大率的巨大差异引发 SM 间负载不均衡。若 GigaThread Engine 将高 TF patch 集中分配到少数 SM,这些 SM 的 Domain Shader 负载激增而其余 SM 空转。Fermi 通过任务重分配缓解:轻负载 patch(低 TF)走快速本地通道直接在当前 SM 完成 DS 计算。重负载 patch(高 TF)的采样结果经 L2 Cache 跨 SM 迁移,由空闲 SM 分担 Domain Shader 工作量。
后续架构演进中,Mesh Shader(Turing 引入)和引擎侧的软件细分方案(如 UE5 Nanite 的 cluster-based LOD)将细分决策收回可编程管线,Tessellator 固定电路的使用率逐渐降低。但在 Fermi 时代,它是实现 DX11 曲面细分的唯一硬件路径。
Concurrent Kernel Execution
Fermi 的 GigaThread Engine 支持同一 CUDA Context 内多个 Kernel 在 GPU 上同时执行。不同 Kernel 的 Thread Block 被独立调度到不同的 SM(或同一 SM 的不同时隙),只要 SM 资源(寄存器、Shared Memory、warp slot)未耗尽,新 Kernel 的 block 即可被启动。对由多个小 Kernel 组成的工作流,这避免了 Kernel A 完成后才启动 Kernel B 的同步开销。但并发 Kernel 共享同一 GPU 内存带宽和 L2 Cache,若多个 Kernel 同时为 bandwidth-bound,并发执行的总吞吐可能低于顺序执行(cache thrashing 和资源竞争)。
跨 CUDA Context 的并发(如计算与图形任务共存)在 Fermi 上通过时间片轮转实现,非硬件级并行。
Unified Virtual Addressing (UVA)
Fermi(Compute Capability 2.0)引入 UVA,CPU 和 GPU 共享同一套 64-bit 虚拟地址空间。具体实现:CUDA Driver 在进程启动时申请一块统一的虚拟地址范围,CPU 内存(pageable / pinned)和 GPU 内存(device memory)被映射到该范围的不同段。应用程序拿到的指针携带地址段信息,CUDA Runtime 根据指针值的高比特判断数据位于 CPU 还是 GPU,自动推断 cudaMemcpy 的传输方向。
UVA 做的是地址语义统一,而非物理内存统一。CPU 与 GPU 之间的数据搬运仍需通过 PCIe 完成,HtoD 和 DtoH 传输的延迟和带宽不受 UVA 影响。UVA 解决的是编程模型层面的指针可移植性。在 UVA 之前,CPU 指针和 GPU 指针是独立的地址空间,cudaMemcpy 必须显式指定源和目标设备。UVA 之后,统一指针可在异构代码中自由传递。
这与 Pascal 架构引入的 Unified Memory(硬件页错误 + 按需迁移)截然不同:Fermi UVA 没有硬件页错误机制,没有自动数据迁移,kernel 访问 UVA 指针指向的 CPU 内存不会触发 on-demand paging,而是直接出错或产生未定义行为。
64-bit 寻址
Fermi 是首款支持 64-bit 虚拟和物理地址的 NVIDIA GPU。GT200 仅限 32-bit 地址空间(4 GB 上限),无法有效利用超过 4 GB 的显存。Fermi 的 64-bit MMU 将虚拟地址翻译为物理地址,支持大于 4 GB 的显存配置和更大的虚拟地址空间。MMU 通过页表 walk 将虚拟地址映射到物理页,TLB 缓存近期翻译结果以减少 walk 开销。
2.7 小结
"通用计算优先"的设计哲学
Fermi 的设计决策围绕一个判断:GPU 的市场将从图形渲染扩展到数据中心的通用并行计算。由此驱动了多项架构选择:
- 完整 32 位整数 ISA 取代 24 位图形优化指令,通用算法不再受限于图形 legacy
- IEEE 754-2008 合规性消除 GPU 与 CPU 的数值可移植性障碍
- DP FMA 的 1:2 峰值比例使 GPU 首次在双精度浮点吞吐上接近 CPU 水平
- ECC 内存保护满足数据中心对静默错误的容忍度要求
- 完整 Cache Hierarchy(L1/L2)降低通用 workload 对显式内存调优的依赖
关键权衡的硬件代价
| 设计决策 | 收益 | 代价 |
|---|---|---|
| Dual Warp Scheduler | 每周期 2 条指令发射,ILP 提升 | 额外的 scheduler 逻辑、Scoreboard 复杂度、执行单元仲裁电路面积 |
| DP FMA Unit ×16 per SM | HPC 市场的 DP 吞吐竞争力 | 消费级 SKU 上这些晶体管被闲置或熔断,die area 浪费 |
| Hot Clock 2× | 计算密集 kernel 的 ALU 吞吐翻倍 | SM 功耗密度集中,散热瓶颈,TDP 250W,后续架构放弃此设计 |
| L1/Shared 可配置分割 | workload-specific 优化空间 | 同一 SRAM 不能同时最大化两者,错误配置导致 cache miss 或共享空间不足 |
| PolyMorph Engine per SM | DX11 Tessellation 硬件加速 | 非图形 workload 上这些晶体管完全闲置,SM 面积 overhead |
| ECC(数据中心 SKU) | 数据完整性保障 | 12.5% 存储 overhead,有效带宽下降,编解码延迟 |
遗留问题与后续演进线索
Fermi 的 Dual Warp Scheduler 是调度能力的必要但不充分扩张:48 个驻留 warp 共享有限的执行资源,scheduler 的选择空间受限于 eligible warp 数量。Hot Clock 的功耗代价在 28nm 节点变得不可接受,Kepler 转向单一时钟域。L1/Shared Memory 的互斥分割在后续架构中通过独立物理存储解决(Maxwell+)。UVA 的地址统一为 Pascal 的 Unified Memory 提供了软件层面的地址空间前提,但硬件级页错误和自动迁移仍需等待 Pascal 的硬件支持。
Fermi 确立了 NVIDIA GPU 的两大设计范式:SM 级别的模块化扩展(后续每代增加 SM 数量、调整每 SM 配置)和 Cache Hierarchy 的统一管理(L2 作为所有访存类型的统一汇聚点)。这两条线从 Fermi 一直延伸到今天的 Blackwell。
三、Kepler (2012)
Kepler 架构于 2012 年发布,以 GK104 与 GK110/GK210 两款核心为代表,是 NVIDIA 设计理念的一次明确转向:从追求理论峰值性能转向对性能功耗比的整体优化。硬件前提是取消 Fermi 时代 2x shader clock(hot clock),将所有执行单元与逻辑电路统一到同一时钟域,彻底消除双时钟域带来的功耗与布线复杂度。然而时钟频率的下降意味着每周期需要发射更多指令才能维持吞吐量,这正是 Kepler 将 SM 内 CUDA Core 数量从 32 扩至 192 的直接动因,即"规模换频率"。
产品线层面,GK104(Compute Capability 3.0)与 GK110/GK210(Compute Capability 3.5/3.7)的分化源于微架构资源的差异化配置。GK104 面向图形与消费级市场,FP64 单元数量被削减至 FP32 的 1/24。GK110/GK210 面向 HPC 与数据中心,保留了完整的 FP64 能力,并引入了 Dynamic Parallelism 与 Hyper-Q 等 GPGPU 专用硬件。两条产品线共享相同的 SMX 基本结构与静态调度机制,但在执行单元配比、寄存器文件容量和功能特性上存在实质性差异。
3.1 ISA
Kepler 的 ISA 扩展围绕两个目标展开:降低数据移动开销(Warp Shuffle)和扩展寄存器寻址空间以容纳更复杂的内核。CUDA 开发者编写的是 PTX 虚拟 ISA,PTX 在编译时由 ptxas 转换为 SASS 原生机器码,SASS 才是 SMX 硬件实际译码与执行的指令格式。以下讨论的 ISA 改动同时体现在 PTX 抽象层与 SASS 编码层。
寄存器数量扩展与指令编码变化
Fermi 时代,SASS 指令编码中寄存器操作数字段宽度为 6 bit,可索引 0–63 号通用寄存器,单线程寄存器上限因此被硬编码在指令格式中。对于具有大量 live variables 的复杂内核(如多轮迭代的高阶 stencil 计算),63 个寄存器往往不足以容纳工作集,编译器被迫通过 Register Spilling 将变量溢出到 Local Memory(位于全局地址空间的片外 DRAM 区域),每一次 spill/fill 都产生至少一次经 L1/L2 到 DRAM 的 round-trip 访存。
Kepler 将 SASS 指令编码中的寄存器操作数字段从 6 bit 扩展至 8 bit,单线程可索引的寄存器范围从 0–63 扩展至 0–255。PTX 层面通过 .reg 声明与对应的 ABI 调整暴露这一能力。硬件代价是指令字长的增加:每个携带三个寄存器操作数的算术指令在 SASS 中需要额外 6 bit(每个操作数 +2 bit),对 I-Cache 的有效容量产生轻微压力。但相对于 spill 到 DRAM 的访存代价,指令编码膨胀的代价可忽略。
单线程寄存器用量的增加直接影响 Occupancy。GK110 每个 SMX 的 Register File 容量为 256 KB(64K × 32-bit 寄存器),若每个线程使用 255 个寄存器,单个 SMX 最多驻留 256 个线程(8 个 Warp),远低于 64 个 Warp 的物理上限,延迟隐藏能力急剧下降。GK210 将 RF 容量翻倍至 512 KB(128K × 32-bit),同一占用率下的单线程寄存器预算翻倍:例如维持 32 个 Warp 时,每线程可用寄存器从 128 个增至 255 个。对于 HPC 场景中寄存器压力极大的内核,GK210 的 RF 扩容是将 Occupancy 从不可接受拉升到可用的关键。
Warp 级 Shuffle 指令
Kepler PTX/SASS 新增 Warp Shuffle(SHFL)指令族,包括 shfl.up、shfl.down、shfl.bfly(XOR-based butterfly)和 shfl.idx(任意线程索引)。在 SHFL 出现之前,同一 Warp 内线程间的数据交换唯一途径是通过 Shared Memory:源线程执行 st.shared,经 __syncthreads() 同步后目标线程执行 ld.shared,最少涉及一次写、一次同步屏障、一次读,路径长且消耗 Shared Memory 带宽。
SHFL 的硬件路径完全绕过 Shared Memory 和 Load/Store 单元。源线程的寄存器值通过 SMX 内部的 shuffle network(一种基于 XOR 路由的片上互连)直接传送到目标线程的寄存器,延迟约几个时钟周期,与一次寄存器读取相当。开发者可观察到的效果:
- Warp 内 scan、reduce、broadcast 等模式不再需要分配 Shared Memory,Shared Memory 压力降低,可腾出容量用于其他数据缓存。
- 省去了
__syncthreads()的同步开销,尤其在小粒度数据交换(如邻域差分)场景下,warp 内延迟明显降低。 - 但
SHFL仅限于同一 Warp 内的 32 线程之间交换数据,跨 Warp 通信仍需 Shared Memory 或全局内存。
64 位原子操作扩展
Fermi 已原生支持 64 位整型的 atomicAdd 与 atomicCAS。Kepler(GK110)在此基础上扩展了 atomicMin、atomicMax、atomicAnd、atomicOr、atomicXor 的 64 位版本,PTX 指令为 atom.{op}.u64 / atom.{op}.s64。64 位浮点原子操作(atomicAdd.f64)仍须通过 atomicCAS 循环实现:读取当前值、在寄存器中执行加法、用 atomicCAS 尝试写回,失败则重试。限制源于 FP64 加法不具备结合律,无法像整数那样直接在 L2 的原子单元上拆分为 compare-and-swap 循环。64 位整型原子扩展对图计算中的度数统计、大规模计数器数组等场景有直接影响。
3.2 Scheduling
Kepler 引入了**静态调度(Static Scheduling)**机制,取代 Fermi 中以硬件 Scoreboard 为核心的动态调度逻辑。这是 Kepler 微架构中影响最大的变更之一,逻辑是"以编译器换硬件复杂度":将指令依赖分析、延迟计算和发射决策从运行时硬件转移到编译期 ptxas,降低 SMX 控制逻辑的功耗与面积。
静态调度与控制字(64-bit Control Word)
Kepler SASS 指令流中,每 7 条指令后跟随一个 64-bit 的 Control Word(控制字),编码了这 7 条指令的调度元信息。Control Word 的格式并非公开文档,但可通过微基准测试与 SASS 反汇编逆向推断其关键字段:
- Dependency Stall / Stall Count:对于结果延迟可预测的固定延迟指令(如 FP32 FMA 约 6 cycle、整数加法约 4 cycle),编译器在 Control Word 中预先写入依赖该结果的后续指令需要等待的周期数。硬件 Warp Scheduler 读取 Control Word 后,在对应指令发射前自动插入指定数量的停顿周期,无需运行时检测寄存器就绪性。
- Dual-Issue Information:Control Word 标记哪些指令对可以在同一周期双发射(Dual-Issue)。编译器在静态分析阶段识别出无数据依赖、无结构性冲突的独立指令对,并通过 Control Word 告知硬件。Warp Scheduler 只需按 Control Word 的指示发射,无需在运行时进行动态相关性检查。
- Yield Bit:指示当前 Warp 在发射后是否应被暂时搁置,以允许同 SMX 内其他 Warp 获得发射机会,防止单一 Warp 垄断发射带宽。
这一机制改变了 SMX 的调度 data path。Fermi 的路径:Decode → Warp Scheduler → Scoreboard 查询(寄存器粒度就绪性检查)→ Issue Arbitration → Operand Collector。Kepler 简化为:Decode → 读取 Control Word → 按预设计数器停顿 → 发射至 Operand Collector。Control Word 替代了大部分 Scoreboard 的动态查询功能。
硬件 Scoreboard 的简化与保留
静态调度并非万能。对于延迟不可预测的操作(最典型的是全局内存加载,Cache Hit 与 Miss 的延迟差异可达两个数量级,以及 __syncthreads() 屏障),编译器无法在编译期确定准确的等待周期。Kepler 因此保留了一个简化的硬件 Scoreboard,但跟踪粒度从 Fermi 的寄存器粒度降级为Warp 粒度。
具体机制:当一个 Warp 发射了一条 variable-latency 指令(如全局内存 LD),Scoreboard 将该 Warp 整体标记为"未就绪",阻止其在后续周期被选中发射。内存数据返回(经 L2 或 DRAM)并写回 Register File 后,Scoreboard 将该 Warp 重新标记为"就绪"。粗粒度跟踪的代价:即使一个 Warp 中只有一条 long-latency load 在等待,该 Warp 的所有其他就绪指令也无法发射,直到 load 完成。相对于 Fermi 的细粒度跟踪(可跳过等待寄存器发射 Warp 中其他独立指令),Kepler 在极端 mixed-latency 场景下的发射效率存在理论损失。然而对于典型的 data-parallel kernel,大量 Warp 的存在使 Scheduler 可以在其他 Warp 上找到 eligible 指令,粗粒度 Scoreboard 的实际影响被掩盖。
简化的 Scoreboard 还承担 barrier 同步的跟踪:当 Warp 执行 BAR.SYNC 时,Scoreboard 将其标记为 barrier-wait 状态,直到同一 Thread Block 内所有 Warp 都到达屏障后才集体释放。
开发者可观察到的调度行为变化
- 使用
cuobjdump -sass反汇编 Kepler 二进制,可以观察到每 7 条指令后出现的 64-bit Control Word,以及指令对中的 Dual-Issue 标记。 - 静态调度意味着编译器版本(
ptxas的优化能力)对性能的影响增大。同样的 PTX 源码,用不同版本的 CUDA 工具链编译,可能因静态调度信息的质量差异而产生明显性能差距。 - 对于包含大量 pointer chasing 或 divergent memory access 的内核,Kepler 的粗粒度 Scoreboard 相比 Fermi 可能暴露更多调度 bubbles, Occupancy 的重要性因此进一步上升。
3.3 Execution Unit
Kepler 将 SM(Fermi 的称谓)重命名为 SMX(Streaming Multiprocessor eXtreme),主要变化是执行单元的大规模扩张:每个 SMX 容纳 192 个 FP32 CUDA Core,是 Fermi SM 的 6 倍。但 CUDA Core 数量的增加不意味着所有运算类型的吞吐量同比提升。SMX 内部的执行端口分配和资源配比存在明确的非对称设计。
GK104 vs GK110:差异化配置
| 配置项 | GK104(CC 3.0) | GK110(CC 3.5) | GK210(CC 3.7) |
|---|---|---|---|
| FP32 Core / SMX | 192 | 192 | 192 |
| FP64 Unit / SMX | 8 | 64 | 64 |
| FP64:FP32 吞吐比 | 1:24 | 1:3 | 1:3 |
| SFU / SMX | 32 | 32 | 32 |
| LD/ST Unit / SMX | 32 | 32 | 32 |
| RF 容量 / SMX | 256 KB | 256 KB | 512 KB |
GK104 的 FP64 吞吐仅为 FP32 的 1/24,原因在于每个 SMX 仅配置 8 个 FP64 单元,且这些单元与部分 FP32 单元共享发射端口。这种"几乎砍掉"FP64 的策略为 GK104 节省了大量芯片面积与功耗,令其在游戏场景(几乎纯 FP32)中获得更好的面积效率。GK110 的 1:3 比例意味着每 3 个 FP32 Core 配 1 个 FP64 单元,是 Tesla 架构以来最激进的双精度配置,直接服务于 HPC 中的 FP64 密集负载。
Operand Collector 机制深度解释
Operand Collector 是支撑双发射和缓解 Register File bank 冲突的关键硬件结构。要理解其必要性,需先看 RF 的访问约束:
Kepler SMX 的 Register File 为 64K × 32-bit,物理上划分为 4 个独立 bank,每个 bank 每周期只能服务一个 32-byte(8 寄存器)读请求。一次双发射可能涉及最多 2 条指令 × 3 个源操作数 = 6 个寄存器读端口需求。如果 6 个源操作数恰好映射到同一 bank,则会产生 bank conflict,读操作被迫串行化。
Operand Collector 的工作机制:在指令发射前的一个或多个周期,Operand Collector 预取(collect)该指令所需的源操作数,将其暂存于一个小的入口缓冲(entry buffer)中。当指令到达执行阶段时,操作数已从 Operand Collector 直接供给,不再实时访问 RF。这带来了两个关键效果:
- 缓解 bank conflict:Operand Collector 有多个 entry,每个 entry 独立访问 RF bank。即使某条指令的操作数分布在冲突的 bank 上,Operand Collector 可以在多个周期内分步收集,在执行周期一次性提供,将 bank conflict 的延迟隐藏在 collect 阶段。
- 支撑双发射:两条同时发射的指令可以各自从自己的 Operand Collector entry 获取操作数,RF 只需在前序周期提供足够的 aggregate 带宽即可,执行周期的端口压力被分散。
Operand Collector 与 Warp Scheduler 的交互:Warp Scheduler 在发射指令前,先查询 Operand Collector 是否有空闲 entry 以及 RF bank 是否可访问。如果资源不满足,发射被推迟到下一周期。Operand Collector 的 entry 数量和 RF bank 结构因此共同构成 SMX 的 issue rate 上限之一。
执行端口与资源分配的非对称设计
SMX 内 192 个 CUDA Core 并非统一接入一个公共发射端口,而是被划分为 4 个子分区(sub-partition),每两个子分区共享一个 Warp Scheduler 和一个 Dispatch Port。两个 Warp Scheduler 各负责一个 Dispatch Port,形成 Dual-Issue 的物理基础。
执行端口的分配呈现非对称性:
- Port 0:主要服务整数运算(INT32)、地址生成(用于 LD/ST)、位操作和逻辑运算。
- Port 1:主要服务浮点运算(FP32/FP64)和特殊函数(SFU)。
由于 192 个 CUDA Core 中 FP32 单元占绝大多数,而 INT32 单元与 FP32 单元共存于同一 Core 但共享发射端口,整数运算的理论利用上限约为 FP32 的 2/3。当 Port 0 被整数指令占满时,即使 Port 1 仍有空闲 FP32 单元,整数指令也无法"借用"Port 1 的带宽。端口功能划分在硬件上是固定的。
SFU(32 个 / SMX)的理论吞吐约为整数单元的 1/4。SFU 执行超越函数(sin、cos、rsqrt、log、exp)的延迟约为 FP32 FMA 的 4–8 倍,且 32 个 SFU 由所有 Warp 共享。对于大量使用 __sinf 等 intrinsic 的图形或科学计算内核,SFU 容易成为吞吐量瓶颈。开发者可通过 __device__ 级别的 intrinsic 与标准库函数的选择来平衡精度与 SFU 压力。
3.4 Register File
Kepler SMX 的 Register File 容量为 256 KB(64K × 32-bit 寄存器),较 Fermi 的 128 KB 翻倍。GK210 再翻倍至 512 KB。RF 的物理组织结构直接决定指令发射效率、Occupancy 上限和编译器分配策略,容量只是其中一个维度。
物理组织:4-Bank 结构
64K 寄存器物理上组织为 4 个独立 bank(Bank 0–3),每个 bank 容量 16K 寄存器(64 KB),每周期可服务一个 32-byte 读请求(相当于 8 个 32-bit 寄存器)。写回端口通常独立配置,每周期可完成多个写操作。4-bank 设计的目的是将 32 个线程的寄存器访问分散到不同 bank,降低冲突概率。
微基准测试(L5 推断)表明 Kepler 的寄存器到 bank 的映射并非简单的线性 hash,而是将连续线程的同一寄存器编号分散在不同 bank 中。例如 Thread i 的寄存器 R 可能被映射到 Bank (R + i) % 4。交错映射使 Warp 中 32 个线程同时读取各自的 R0 时,访问被均匀分散到 4 个 bank,每周期处理 8 个线程,4 周期完成整个 Warp 的读取,而非全部挤在同一 bank 上串行化。
Register Bank Conflict 与 Reuse
Bank conflict 发生在以下场景:两条同时发射(或紧密连续发射)的指令,其源操作数寄存器经过映射后落到同一个 bank,且访问的线程集合导致该 bank 在同一周期需要服务多个请求。Operand Collector 通过分步收集来缓解这一问题,但如果冲突过于频繁(例如所有操作数都集中在同一 bank),Operand Collector entry 的缓冲能力会被耗尽,发射被迫停顿。
Kepler 硬件层面尚未引入 Maxwell 中正式的 Operand Reuse 机制(Reuse Flag),但编译器在寄存器分配阶段会尽量将同时活跃的操作数分配到不同 bank。SASS 反汇编中可观察到编译器对寄存器编号的选择存在 bank-aware 模式(L5 推断,非官方确认)。判断是否存在严重 bank conflict 的症状:Occupancy 充足但 issue rate 低于理论值,且 cuobjdump 反汇编显示大量独立指令未被双发射。
Occupancy 与单线程 255 寄存器的权衡
SMX 的寄存器分配以 Thread Block 为粒度:Block 分配到 SMX 时,硬件根据该 Block 的线程数和每线程寄存器用量一次性划出所需的 RF 区域。公式化的约束:
- 若每线程使用 128 寄存器,Block 大小为 1024 线程,则每 Block 消耗 128 × 1024 = 128K 寄存器。SMX 容量 64K 寄存器时,一个 SMX 最多驻留 0 个 Block,该配置在 GK110 上不可运行。GK210(128K 寄存器)上刚好容纳 1 个 Block。
- 若每线程降至 64 寄存器,同一 Block 消耗 64K 寄存器,GK110 可容纳 1 个 Block(32 Warp),Occupancy 为 50%。GK210 可容纳 2 个 Block(64 Warp),Occupancy 达到 100%。
GK210 的 512 KB RF 对 HPC 场景的作用在于:允许编译器在不牺牲 Occupancy 的前提下分配更多寄存器以避免 spill。对于大量 live variables 的迭代求解器,GK210 相比 GK110 的性能提升可能主要来自减少了 spill 导致的 DRAM 流量,而非计算吞吐本身的差异。
ECC 对 RF 的影响
GK110/GK210 支持对整个 Register File 的 ECC 保护(SEC-DED,Single Error Correction, Double Error Detection)。硬件代价是额外的校验位存储(约 12.5% 容量开销)和校验计算延迟。启用 ECC 后,RF 有效容量略微下降,读写延迟增加 1–2 cycle。对于长时间运行的 HPC 任务,这一 trade-off 通常可接受。延迟敏感的图形负载可禁用 ECC。
3.5 Memory Subsystem
Kepler 的内存子系统围绕一个决策展开:L1 不再缓存常规全局内存读取。这一决策的动机、实现与补偿机制构成了 Kepler 缓存层次结构调整的主线。
L1 不再缓存全局内存:决策与影响
Fermi 的 16/48 KB L1 cache(可配置)承担两项职责:缓存全局内存读取和缓冲 Local Memory(spill/fill、thread stack)。Kepler 将 64 KB on-chip memory 重新划分为 48 KB Shared Memory + 16 KB L1(固定比例,不再可配置),并明确 L1 不再缓存常规全局内存的 load 操作。全局内存 load 默认绕过 L1,直接发往 L2 Cache。
硬件层面原因:Fermi 的 L1 采用 write-evict 策略,且并非 coherent across SM。全局内存 write 需通过 L2 统一回写,L1 中缓存全局数据带来的 hit rate 在 data-parallel CUDA kernel 中通常较低(多数 kernel 的访问模式对 L1 不友好,如 stride access 或 streaming),而维护 L1 coherence 的硬件开销(tag compare、evict logic、coherence protocol)不可忽视。取消 L1 的全局缓存职责后,Kepler 的 L1 逻辑随之简化,面积和功耗降低。原 L1 的 tag/store 资源被重新用于加速 Local Memory 访问(spill/fill 路径缩短)和 thread stack 管理。
对开发者的直接影响:
- 对全局内存的重复读取不再从 L1 获得低延迟服务,完全依赖 L2 hit 或 DRAM access。对于具有良好数据复用(reuse)的内核,需要显式将数据移入 Shared Memory 以获得片上缓存效果。
- 对于只读且随机访问的数据(如查找表、常量系数),Kepler 引入了 Read-Only Data Cache 作为替代路径。
Read-Only Data Cache 的引入
Kepler SMX 内新增 48 KB Read-Only Data Cache(RO Cache),物理上复用了 Texture Cache 的硬件路径(包括 Texture Cache 的 tag array、data array 和 miss-handling 逻辑)。RO Cache 专门用于缓存通过 __ldg()(load global with cache hint)内部函数加载的只读全局数据。
__ldg() 的硬件路径:当 SMX 内的 LD/ST Unit 解码到 __ldg 指令时,请求被路由到 Texture/RO Cache 路径而非常规全局 load 路径。RO Cache 具有更高的读取端口数和针对随机访问优化的替换策略(类似 Texture Cache 的 2-way or 4-way LRU),对于 warp-wide broadcast(32 线程读取同一地址)具有 native 支持,可通过 single tag lookup + multi-cast data delivery 降低带宽消耗。
RO Cache 的引入是对"L1 不再缓存全局"的补偿:将只读数据从常规全局路径中分离出来,利用已有的 Texture Cache 基础设施提供低延迟读取,无需为常规全局读写重建复杂的 L1 coherence。
PRT:Outstanding Request 管理的重构
Fermi 使用 MSHR 追踪 L1 的 outstanding miss,每个 coalesced miss 独占一个 entry。当 warp 内线程访问的地址分散、无法良好 coalesce 时,一条 load 指令可能消耗多个 MSHR entry,outstanding request 的容量受 coalescing 效率制约。
Kepler 引入 PRT(Pending Request Table)替代 MSHR,从根本上解耦了这一约束。PRT 的分配粒度不再是"每个 coalesced miss",而是"每个 warp 的每条访存指令"。一个 warp 发出一条 load 指令时,无论其 32 个线程的地址如何分散、产生多少个独立的 cache line request,硬件只分配一个 PRT entry。该 entry 内部记录 pending request 计数与各线程的地址 offset。L2 返回数据时携带 PRT entry ID,硬件逐线程回填,直到所有线程完成后释放整个 entry。
Kepler 每 SMX 约 45 个 PRT entry(其中 44 个可用于用户访存),microbenchmark 实测得出的数字。它直接决定了可并发推进访存的 warp 数:当活跃 warp 数达到 45、每个 warp 有 1 条 outstanding load 时,PRT 耗尽,实测行为表明访存延迟出现阶跃式突变。
PRT 相对 MSHR 的根本改进:outstanding request 容量不再受 uncoalesced request 数量的影响。Fermi 上一个 scatter 访问模式可能一次性耗光大量 MSHR entry。Kepler 上同样的 scatter 模式只消耗一个 PRT entry,并发访存能力由 entry 数决定,与地址分散程度无关。Kepler 对不规则访存模式的容忍度因此提高。后续 Volta 架构的 L1 stream cache 进一步演进,允许无限数量的 outstanding miss in flight,TAG 与 PRT 概念合并,延续了 PRT 的设计思路。
L2 缓存扩容与原子操作合并
GK110 的 L2 缓存容量从 Fermi 的 768 KB 增至 1536 KB,bank 数量和聚合带宽同步提升。L2 作为所有 SMX 共享的片上最后一级缓存,承担以下职责:
- 全局内存 load/store 的统一缓存与回写缓冲(write-back buffer)。
- 原子操作的合并与排序。
- Host-GPU 数据传输(pinned memory、DMA)的缓冲。
- Texture/RO Cache miss 的二级服务。
Kepler L2 引入了原子操作合并(Atomic Coalescing)机制:当多个 SMX 对同一地址发起原子操作时,L2 的原子单元(Atomic Unit)可以在 L2 内合并处理,不必每个操作都直接访问 DRAM。以 atomicAdd 为例,若 4 个 SMX 在同一周期对地址 A 发出 atomicAdd,L2 Atomic Unit 会将 4 个增量值在片上累加,仅将最终结果写回 DRAM 一次。对并行归约、直方图统计等原子密集型操作,这一机制很关键。开发者可观察到:atomic-intensive kernel 在 Kepler 上的吞吐远高于 Fermi,且性能对并发原子数量的敏感度降低。
GPUDirect RDMA(简要)
Kepler 引入的 GPUDirect RDMA 允许第三方 PCIe 设备(如 NIC、SSD 控制器)直接对 GPU 显存发起 DMA 读写,绕过 Host CPU 和系统内存。硬件路径上,NIC 通过 PCIe 的 Peer-to-Peer(P2P)机制直接寻址 GPU 显存的物理地址,由 GPU Memory Controller 处理来自 PCIe 的 DMA 请求,数据经 L2 Cache 缓冲后写入目标显存区域。GPU 数据摄取的延迟从"设备 → CPU 内存 → GPU 内存"的两跳降低为一跳,对需要高吞吐低延迟网络 I/O 的 HPC 场景(如 MPI 多节点通信)有直接收益。
3.6 Function Feature
以下功能特性并非所有 Kepler GPU 共享。Dynamic Parallelism 与 Hyper-Q 仅限 GK110/GK210,体现了面向 HPC 市场的硬件投入。
Dynamic Parallelism(GK110/GK210 独占)
Dynamic Parallelism 允许正在 GPU 上执行的 kernel(父内核)无需 CPU 介入即可直接启动新的 kernel(子内核)。核心硬件支撑是 Grid Management Unit(GMU) 和 CUDA Work Distributor(CWD)。
完整的父→子内核启动路径:
- 父内核中某 Warp 的线程执行
cudaLaunchDevice(或 PTXgriddepcontrol.launch),在 SMX 上生成一个 kernel 启动请求。 - 该请求被写入 GMU 的 Launch Queue(片上 FIFO)。GMU 是 GK110 新增的专用硬件单元,负责管理子内核的 grid 创建与依赖跟踪。
- GMU 从 Launch Queue 中取出请求,为新 grid 分配 grid ID、计算所需资源(SMX slot、寄存器、Shared Memory),并将其提交给 CWD。
- CWD 将子 kernel 的 Thread Block 分派到空闲的 SMX 上,与父内核的 block 共享 GPU 资源。
- 父内核可通过
cudaDeviceSynchronize(PTXgriddepcontrol.sync)等待子内核完成,或与之并行执行。
Dynamic Parallelism 解决了 CPU 端难以表达动态嵌套并行的问题。递归数据结构遍历(如自适应网格细化、N-body 树遍历)中,每一层迭代的并行度在运行时才确定,Dynamic Parallelism 允许 GPU 根据中间结果自主决定下一级的 launch 参数,避免反复 kernel 退出→CPU 调度→重新 launch 的开销。
硬件代价:GMU 和 CWD 的额外面积与功耗。Launch Queue 深度限制了可同时 inflight 的子内核数量。父子内核间的同步通过 GMU 的 dependency tracker 硬件实现,引入额外的延迟。
Hyper-Q(GK110/GK210 独占)
Hyper-Q 将 GPU 的硬件工作队列从 Fermi 的单个增至 32 个,每个队列由 Host Stream 独立提交。Fermi 的单一硬件队列导致了一个隐蔽的性能问题:当多个 CPU 线程或 MPI 进程各自创建 CUDA Stream 并向 GPU 提交 kernel 时,这些 Stream 在驱动层被串行化合并到单一硬件队列中。即使不同 Stream 的 kernel 之间没有数据依赖,硬件上也被强制顺序执行,SMX 资源闲置,这就是 false dependency(虚假依赖)。
Hyper-Q 的 32 个硬件工作队列由 GigaThread Engine 并行轮询。多个 Stream 的 kernel 同时提交时,GigaThread Engine 可以从不同队列中并行提取 Block,分派到空闲的 SMX 上。直接影响:MPI+CUDA 混合程序中,多个 MPI rank 可以各自绑定一个 Stream,独立地向同一 GPU 提交工作,GPU 的 SMX 利用率不再因串行化而降低。
开发者可观察到的效果:在支持 Hyper-Q 的 GK110/GK210 上,多 Stream 并发场景的有效占用率和 throughput 明显高于 Fermi。在不支持 Hyper-Q 的 GK104 上,多 Stream 的并发效果取决于驱动层的软件队列调度。
GPU Boost
GPU Boost 是 Kepler 引入的功耗-频率动态调整机制。片上功耗监控单元(Power Monitor)每周期采样 SMX、Memory Controller、L2 等组件的功耗状态,与 TDP(Thermal Design Power)预算比较。实际功耗低于 TDP headroom 时,GPU Boost 逐步提升 GPU Core Clock。接近或超过 TDP 时降低频率。
GPU Boost 对性能分析的影响:固定 clock frequency 假设不再成立。同一个 kernel 在不同温度、不同 board 上的执行时间可能存在差异。性能分析时需关注 achieved frequency 而非标称频率。
3.7 小结
Kepler 取消 hot clock 后,单 SM 每周期吞吐下降到 Fermi 的三分之一,必须靠 6 倍 CUDA Core 数量补回来。支撑这一规模化的前提是静态调度:把依赖分析、延迟计算、双发射决策从运行时 Scoreboard 转移到编译期的 Control Word,使 SMX 的 Warp Scheduler 逻辑简化,腾出面积容纳 192 CUDA Core。代价是编译器的调度质量直接决定性能,同样的 PTX 源码在不同版本 ptxas 上的性能差异可能比 Fermi 更大。对于 variable-latency 操作,Kepler 保留了简化的 Warp 粒度 Scoreboard,粗粒度跟踪在极端场景下会引入发射 bubbles。
"以规模换频率"体现在取消 hot clock 后,用 6 倍于 Fermi 的 CUDA Core 数量弥补单周期吞吐的下降。192 个 Core 需要对应扩张的 Operand Collector、RF bank、Dispatch Port 来 feeding,整个 SMX 的面积远大于 Fermi SM。GK104 通过砍掉 FP64(1:24)来控制总面积,专注于 FP32 吞吐。GK110 保留完整 FP64(1:3),面向 HPC 的 area efficiency 相对较低,但获得了 double-precision 吞吐的竞争力。GK210 进一步将 RF 翻倍至 512 KB,直接服务于寄存器压力极大的 HPC 内核。
产品线分化的微架构含义:GK104 与 GK110 的差异化涉及整个芯片的面积预算、功耗分配和市场定位的重新平衡,远不止"切掉几个单元"。GK104 的 1:24 FP64 比例意味着芯片面积被最大程度地用于 FP32 吞吐,这正是游戏渲染所需。GK110 的 Dynamic Parallelism 和 Hyper-Q 需要 GMU、CWD、32 个硬件队列等额外硅片面积,这些投入在消费级产品中被视为不必要的 overhead。Kepler 确立的"消费级 vs. HPC"双轨产品线策略,被后续 Maxwell/Pascal 架构延续。
L1 不再缓存全局内存的决策,配合 Read-Only Data Cache 的引入和 L2 的翻倍,构成了 Kepler 缓存层次结构的主要调整。出发点是 area-power-performance 的综合权衡:取消低 hit-rate 的 L1 全局缓存功能,简化 L1 逻辑,将节省的资源投入更大、更统一的 L2,通过 RO Cache 保留对只读数据的低延迟访问路径。对开发者而言,Shared Memory 的显式管理变得更加重要:如果内核存在数据复用,必须主动将其移入 Shared Memory,不能依赖 L1 的隐式缓存。
Kepler 的静态调度思想、SMX 规模化路径、以及消费/HPC 双轨产品策略,直接延续到后续 Maxwell 和 Pascal 的设计中。Maxwell 在 Kepler 静态调度的基础上进一步引入 SASS Control Code 的正式化。Pascal 的 GP100 则在静态调度框架下重新引入更激进的硬件 prefetch 和 cache 策略。Kepler 是这一演进链条的起点。
四、Maxwell - Pascal (2014-2017)
Maxwell 于 2014 年在 28nm 工艺上推出,未依赖制程节点跃迁,而是通过 SM 内部结构的精简与调度逻辑的硬化,将每瓦性能推至 Kepler 的两倍。核心策略是将调度控制的重心从硬件动态分析彻底移向编译器静态规划:编译器通过指令中显式编码的依赖延迟与同步信息直接驱动 Warp Scheduler 的发射行为,硬件 Scoreboard 退居辅助角色。Warp Scheduler 和执行单元的耦合关系因此可以简化,为 SM 的物理分区化和时序收紧创造了前提。
Pascal 于 2016 年沿用 16nm FinFET 工艺,完整继承了 Maxwell 的静态调度框架与 ISA 编码,但执行了一条关键的产品线分化策略:
- GP10x (GP104/GP102):面向消费级图形市场,延续 Maxwell 的四象限 SM 布局,128 FP32 Core/SM,FP32:FP64 = 32:1,搭配 GDDR5X。
- GP100:面向 HPC/数据中心,SM 重构为双分区布局,64 FP32 Core/SM + 32 FP64 Core/SM,FP32:FP64 = 2:1,搭配 HBM2 与 NVLink。
这两种 SM 配置在 dispatch port、execution unit、memory interface 上存在实质性差异,后续各节将分别处理,避免混为一谈。
两代架构的演进关系:Maxwell 完成了静态调度模型和模块化 SM 的工程验证。Pascal 将该模型复制到两种差异化的产品形态上,分别服务图形吞吐和计算密度两条赛道。
4.1 Instruction Set Architecture
4.1.1 Maxwell:SCHI 静态调度框架
Maxwell 的 ISA 层面最重要的变化是引入了 Schedule Instruction (SCHI) 机制,将 Kepler 的 64-bit 控制字方案替换为一种更紧凑、更直接的编译器-硬件契约。
SCHI 的编码结构与功能
SCHI 是一条 32-bit 的控制指令,与随后的 1-3 条普通指令打包成一个 "3+1" 指令组。SCHI 内部编码的信息直接决定 Warp Scheduler 的发射行为:
- Stall Count (等待周期数):编译器根据指令间的数据依赖延迟,精确填入下一条指令需要等待的时钟周期数。Warp Scheduler 读取该字段后,在指定周期数内不发射该指令组中的后续指令。对于 FP32 指令,编译器通常填入 ~3 周期以覆盖依赖性延迟。对于 LD/ST 指令,填入的等待周期可能长达数十至上百周期,以覆盖 L2 cache miss 或 device memory 的访存延迟。
- WarpYield Flag:当该位被置位时,Warp Scheduler 在完成当前指令组的发射后,主动让出 issue slot,切换到下一个 eligible warp。编译器在指令组的最后一条指令上设置该位,以提示调度器"本组指令已充分利用当前 warp 的并行度,可以切换到其他 warp"。
- Barrier 同步标记:SCHI 可以编码对特定 barrier 的等待操作,用于
__syncthreads()等线程块内同步场景。Warp 在遇到 barrier 标记时会进入等待状态,直到同一线程块的所有 warp 都到达该 barrier 点才恢复调度。
通过 SCHI,编译器在离线阶段完成了指令流的时序规划。Warp Scheduler 在运行时的职责简化为:解析 SCHI 中的控制字段,按顺序执行发射/等待/切换操作,无需动态依赖分析或乱序调度。
Scoreboard 的规模缩减
Kepler 的 Scoreboard 需要跟踪每条指令的写回状态以判断后续指令的源操作数是否可用。Maxwell 中大部分职责被转移至编译器:编译器通过 Stall Count 精确控制指令间距,硬件 Scoreboard 的跟踪粒度可以放宽。Maxwell 的 Scoreboard 仅需处理少数编译器无法静态预测的延迟场景(如不可预测的 memory 返回延迟、atomic 操作的完成等待),物理规模相比 Kepler 缩减。直接收益:Scoreboard 的功耗和面积占用降低,Scoreboard lookup 在关键路径上的延迟缩短,为时序收紧创造了条件。
Warp Scheduler 与 32 CUDA Core 的耦合
Maxwell 的 SMM 被划分为四个子分区,每个子分区配备 32 个 CUDA Core 和 1 个 Warp Scheduler。一个 Warp 恰好包含 32 个线程,一条 Warp 指令的发射天然匹配 32 个 CUDA Core 的执行宽度:每个线程对应一个 Core,无需跨子分区的操作数路由或结果写回仲裁。1:1 的映射关系消除了 Kepler 中一个 Warp 需要被拆分到多个调度端口、操作数需要在多个执行单元簇之间路由的复杂性。
Maxwell 保留了 Dual-issue 能力,但用途发生了根本改变:不再用于发射两条同类型的算术指令(32 Core 已足以在一个周期内消耗完整 Warp 的算术结果),而是用于 ALU 与 SFU 的重叠执行。当一条 Warp 指令需要 CUDA Core(ALU 路径),另一条需要 SFU(特殊函数路径)时,Dual-issue 允许两条指令在同一周期内分别从各自的 dispatch port 发射,ALU 和 SFU 并行执行,提升功能单元利用率。
Operand Reuse 机制
Maxwell 将 Operand Reuse Cache 作为 ISA 契约的一部分暴露给编译器:编译器在指令的操作数上设置 .reuse 标记,提示硬件"该操作数将在后续指令中被立即重新使用",硬件据此将该操作数暂存在靠近 ALU 的微型缓存中,后续匹配指令直接从缓存取数。数据路径变化:
- 正常路径:Operand Collector → Register File Read Port → 操作数 → Execution Unit
- Reuse 路径:Operand Reuse Cache → 操作数 → Execution Unit(绕过 RF Read)
Reuse Cache 的容量、命中流程与编译器标记策略在 4.4.1 节的硬件实现中展开。
4.1.2 Pascal:继承与功能性扩展
Pascal (Compute Capability 6.x) 完全继承了 Maxwell 的 SCHI 静态调度框架、"3+1" 指令打包格式、Warp Scheduler 与 32 Core 的耦合方式以及 Operand Reuse 机制。ISA 层面的扩展集中在数据类型和原子操作上,且这些扩展在产品线之间存在差异。
FP16 运算指令(GP100)
GP100 的每个 FP32 CUDA Core 增加了对原生 FP16 的支持。ISA 中新增了 FP16 算术指令,允许在一个时钟周期内完成两个 FP16 FMA 操作,条件是操作数以 half2 向量形式打包(即两个 16-bit 值打包成一个 32-bit 寄存器)。GP100 SM 的理论 FP16 吞吐率因此达到 FP32 的两倍。
GP100 的 FP16 实现方式是利用现有 CUDA Core 的 SIMD 能力,通过指令层面的打包并行完成,而非引入专用的矩阵乘法硬件(Tensor Core 自 Volta 才出现)。每个 FP32 Core 在执行 FP16 half2 指令时,将内部乘法器和加法器拆分为两个 16-bit 数据通路,分别处理打包的两个半精度元素。晶体管开销极小,FP16 吞吐翻倍,但矩阵乘法的效率远不及后续架构的 Tensor Core。
INT8 点积指令(GP10x)
面向推理应用的 GP104/GP102 引入了 __dp4a (Dot Product of 4-element 8-bit vectors with Accumulation) 指令。该指令在单次操作中完成四对 8-bit 整数的乘法,并将四个乘积累加到一个 32-bit 整数累加器中。GP104 的 CUDA Core 在执行 __dp4a 时,将其标量 ALU 拆分为四个 8-bit 乘法单元和一个 32-bit 累加树,实现 INT8 理论吞吐率为 FP32 的四倍。
__dp4a 仅存在于 GP10x 产品线,GP100 不支持该指令。这一产品线差异反映了 Pascal 的设计意图:GP100 面向训练(需要 FP16),GP10x 面向推理(需要 INT8)。
原子操作扩展(全线)
Pascal 全线扩展了原子操作的类型和范围:
- **64-bit double **
atomicAdd:ISA 层面新增对double类型的原子加法支持。此前架构仅支持 32-bit 整型原子操作。Pascal 的 64-bit FP64 原子操作需要 SM 内部的 FP64 单元配合 L2 cache 的原子协议完成,延迟远高于 32-bit 整型原子操作。 - 系统级原子操作:通过在原子指令后缀添加
_system修饰符(如atomicAdd_system),操作范围扩展到整个系统,包括多个 GPU 和 CPU 的内存空间。硬件实现上,系统级原子操作需要通过统一的内存一致性协议(由 NVLink 或 PCIe 承载)广播到其他参与设备,延迟和吞吐量远低于 device-level 原子操作。ISA 引入该原语的主要目的是为 Unified Memory 和多设备协同计算提供底层同步手段。 - NVLink 远程原子操作(GP100):GP100 通过 NVLink 支持对远程 GPU 显存直接执行原子操作,这是 GP100 独有的能力,GP10x 不具备。
4.2 Scheduling
4.2.1 Maxwell:编译器驱动的静态调度
Maxwell 的调度核心是一条编译器-硬件流水线:编译器通过 SCHI 将时序信息烧录到指令流中,Warp Scheduler 在运行时仅需顺序解析和执行这些信息。
Warp Scheduler 的职责简化
每个 SMM 子分区的 Warp Scheduler 管理一组驻留 warp(通常 8-16 个)。每周期,Warp Scheduler 按以下逻辑工作:
- 读取当前 SCHI 中编码的 Stall Count。若 Stall Count > 0,递减计数器,本周期不发射指令。
- 若 Stall Count == 0,检查当前指令组中是否有待发射的指令。
- 检查指令的 Scoreboard 状态(处理编译器无法预测的延迟,如 cache miss)。
- 若指令就绪,通过 Dispatch Port 发射到对应的执行单元(32 CUDA Core、8 LD/ST 或 8 SFU)。
- 若 WarpYield 位置位,发射完成后标记该 warp 为非 eligible,切换到下一个 warp。
流程的顺序性和确定性使 Warp Scheduler 不需要复杂的动态调度逻辑(如 Tomasulo 算法的保留站、重排序缓冲区等),硬件实现可以非常轻量。
延迟隐藏机制
Maxwell 依赖 Thread-Level Parallelism (TLP) 隐藏延迟。每个 SMM 支持多达 64 个 resident warp(2048 线程),当某个 warp 因数据依赖(SCHI Stall Count 未到期)或访存延迟(LD/ST 等待 memory 返回)而停顿时,Warp Scheduler 切换到另一个 eligible warp 继续发射。静态调度模型下,warp 切换的决策同样由 SCHI 中的 WarpYield 位指导,编译器在预估当前 warp 的指令级并行度耗尽时主动设置 Yield,提示调度器切换。
工作负载重叠
Maxwell 在异步计算(graphics/compute overlap)方面延续了静态分区模型。SMM 的四个子分区可以被静态分配给 graphics 和 compute 工作负载,但动态负载均衡能力有限。当 compute warp 和 graphics warp 共享同一个 SMM 时,子分区级别的 Warp Scheduler 各自独立调度,不存在跨子分区的全局仲裁。
4.2.2 Pascal:继承与 Instruction-level Preemption
Pascal 的 Warp Scheduler 工作方式与 Maxwell 完全一致:SCHI 解析、Stall Count 递减、WarpYield 切换、Scoreboard 辅助检查。调度核心未被修改。
Pascal 在系统级调度层面引入了 Instruction-level Preemption,其具体实现因产品线而异。
GP100:Compute Instruction-level Preemption
GP100 支持在任意指令边界中断 compute kernel 的执行。实现机制:
- 当抢占请求到达时,Warp Scheduler 在当前指令执行完成后暂停该 warp 的调度。
- SM 保存被抢占 warp 的完整上下文:包括 PC、寄存器状态、Scoreboard 状态、SCHI 解析器的内部状态(当前 Stall Count 计数器等)。GP100 的每个 SM 配备了专用的上下文保存 SRAM,用于快速保存/恢复抢占状态。
- 被抢占的 thread block 被标记为 suspended,SM 将执行资源分配给高优先级任务。
- 抢占完成后,上下文从保存 SRAM 恢复,warp 从被中断的指令边界继续执行。
Compute Instruction-level Preemption 的完整上下文保存/恢复需要一定周期(L5 推断:数十至上百周期,取决于 register footprint),其开销与 kernel 的寄存器使用量直接相关。对于寄存器使用量大的 kernel,抢占延迟更高。
GP10x:Pixel-level / Thread-level Preemption
面向图形的 GP10x 产品线不支持 compute instruction-level preemption,而是提供两种图形专用的抢占粒度:
- Pixel-level Preemption:在图形管线中,抢占粒度为单个 pixel/fragment 的边界。当抢占请求到达时,当前正在处理的 pixel shader 执行完成后即可切换。
- Thread-level Preemption:在 compute 工作负载上,GP10x 的抢占粒度为 thread block 级别,而非 GP100 的 instruction 级别。GP10x 不能在一个 thread block 的执行过程中间打断它,只能等整个 thread block 完成后才能切换。
这一产品线差异的硬件根源在于 GP100 配备了专用的抢占上下文保存 SRAM 和更复杂的 warp 状态管理逻辑,而 GP10x 为控制成本未集成这些硬件。
抢占的应用场景
- GP100 的 compute preemption 面向数据中心多租户场景:高优先级 inference 请求可以中断低优先级 training job。
- GP10x 的 pixel/thread preemption 面向 VR 的 Asynchronous Time Warp (ATW) 和调试工具支持。
- Pascal 还通过改进的异步计算引擎(Async Compute Engine)改善了 graphics/compute 工作负载的动态重叠能力,但 SM 内部仍然是静态分区模型。
4.3 Execution Unit
4.3.1 Maxwell:四象限 SMM 设计
Maxwell 对 Kepler 的 SMX 做了彻底的物理重构。SMM(Streaming Multiprocessor Maxwell)采用 四象限 布局,将 128 个 FP32 CUDA Core 均匀分布在四个独立的子分区中。
子分区的物理结构
每个子分区包含:
- 32 个 FP32 CUDA Core(标量 ALU)
- 1 个 Warp Scheduler + 指令缓冲(64 条指令容量)
- 8 个 LD/ST Unit
- 8 个 SFU
- 1 个 64KB Register File 分区
- 独立的 Scoreboard(精简版)
- 独立的 Operand Reuse Cache
四个子分区之间几乎无共享资源,形成物理上的强隔离。硬件含义:
- 一个 warp 一旦分配到某个子分区,其整个生命周期内的指令发射、操作数读取、执行、结果写回都在该子分区内完成,不跨越子分区边界。
- 子分区之间不存在操作数路由网络或跨分区仲裁逻辑,消除了 Kepler SMX 中复杂的内部互连和竞争。
- 每个子分区的功耗和时序可以独立优化,不受其他子分区活动的影响。
时序收紧与延迟降低
四象限设计的直接收益是核心流水线的时序收紧。通过消除跨子分区的数据通路和仲裁逻辑,关键路径长度缩短:
- 依赖性 FP32 浮点运算(如
FMAfollowed byFMA,第二个操作数依赖第一个结果)的延迟从 Kepler 的 ~6 周期缩短至 ~3 周期。 - 更短的流水线意味着在相同的 resident warp 数量下,warp 从停顿到恢复执行的周转更快,有效提升了执行单元的利用率。
- 编译器在 SCHI 中填入的 Stall Count 也相应缩短,指令组之间的气泡减小。
Hot Clock 的移除
自 Fermi 起 NVIDIA 采用核心频率两倍于调度器频率的 "Hot Clock" 设计:CUDA Core 等执行单元在 2x 频率下运行,Warp Scheduler 等控制逻辑在 1x 频率下运行。Maxwell 放弃了这一设计,核心与调度逻辑同频运行。
移除 Hot Clock 的权衡:
- 统一频率平面消除了跨时钟域的同步开销和额外的功耗,也简化了时序收敛。整个 SM 在同一频率平面内运行,减少了 clock tree 的复杂度。
- 代价是单个 CUDA Core 的每周期吞吐不变,但绝对频率不再享受 2x 倍频。为弥补频率损失,Maxwell 选择堆叠更多 SM:GM204 集成 16 个 SMM(2048 FP32 Core),而前代 GK104 仅 8 个 SMX(1536 FP32 Core)。通过面积效率的提升,Maxwell 在相近 die size 下塞入了更多 SM。
INT32 乘法单元的移除
Maxwell 为了追求极致的面积效率,移除了完整的 32-bit 整数乘法单元。32-bit 整数乘法被拆分为多条 16-bit MAD (Multiply-Add) 指令的序列来模拟。
权衡分析:
- 移除 32-bit 乘法单元后,每个子分区节省了 32-bit 乘法器的面积,释放的晶体管用于增加 CUDA Core 数量或其他功能单元。
- 代价是 32-bit 整数乘法的指令级延迟从单条指令变为多条指令的序列,吞吐量下降。对于依赖 INT32 乘法的应用(如密码学、哈希计算、某些图算法),Maxwell 的性能远低于 Kepler。
- 开发者可观察症状:涉及
int类型乘法的 kernel,在 Maxwell 上的 IPC 相比 Kepler 可能下降 3-4x。若将算法改写为 16-bit 乘法或避免整数乘法,性能可恢复。
4.3.2 Pascal:SM 的产品线分化
Pascal 未延续 Maxwell 的统一 SM 设计,而是根据目标市场演化出两种 SM 配置。
GP10x (GP104/GP102):图形线的 SM 延续
GP104(用于 GTX 1080/1070 等)的 SM 结构基本复刻 Maxwell SMM:
- 四象限布局,每个子分区 32 FP32 CUDA Core
- 每个 SM 共 128 FP32 Core
- FP64 单元削减至每 SM 仅 4 个 FP64 Core,FP32:FP64 理论性能比 = 32:1
- 独立的 Warp Scheduler/子分区,SCHI 静态调度
- 每个子分区 8 LD/ST、8 SFU
GP104 的 SM 增加了一个独立的半精度向量单元(per-subpartition),用于执行打包的 FP16 运算,但主要面向 HDR 渲染等图形任务,而非深度学习训练。该单元的吞吐率远低于 GP100 的 FP16 SIMD 路径。
GP100:计算线的 SM 重构
GP100 的 SM 经过根本性重构,不再延续 Maxwell 四象限设计:
- 双分区布局:每个 SM 被切分为 两个子分区(非四个),每个子分区包含:
- 32 个 FP32 CUDA Core
- 16 个 FP64 CUDA Core
- 1 个 Warp Scheduler
- 8 个 LD/ST Unit
- 8 个 SFU
- 1 个 Register File 分区(容量 per-subpartition 较 GP10x 增加)
- 每 SM 总计:64 FP32 Core + 32 FP64 Core,FP32:FP64 = 2:1
GP100 双分区设计的工程逻辑:
- FP64 单元占用面积较大,若沿用四象限布局,每个子分区需要集成 8 个 FP64 Core,子分区的面积和布线复杂度会随之上升。
- 改为双分区后,每个子分区可以容纳更多的 FP64 Core(16 个),同时保持 Warp Scheduler 与 32 FP32 Core 的 1:1 映射关系(一条 Warp 指令填满 32 Core)。
- 但双分区意味着每 SM 只有 2 个 Warp Scheduler(而非 4 个),每 SM 的指令发射带宽减半。GP100 通过集成更多 SM(60 个)来弥补单 SM 发射带宽的下降。
16nm FinFET 的频率红利
Pascal 全线受益于 16nm FinFET 工艺的开关速度提升:
- GP104 的 boost 频率可达 ~1.7-2.1 GHz,相比 Maxwell GM204 的 ~1.2-1.3 GHz 提升约 40-60%。
- GP100 的频率略低于 GP104(~1.3-1.5 GHz boost),因 HBM2 接口和 FP64 单元的功耗预算限制了频率空间。
- 频率提升直接转化为单 Core 性能增长(每周期吞吐 × 频率),这是 Pascal 性能提升的主要来源,而非微架构层面的 IPC 改进。
4.4 Register File
4.4.1 Maxwell:分区化设计与 Operand Reuse Cache
Maxwell 的每个 SMM 配备 64K 个 32-bit 寄存器,总容量 256KB,与 Kepler GK110 相同。但内部组织结构为适应四象限布局进行了重构。
四个独立的 64KB RF 分区
256KB Register File 被物理分割为四个 64KB 分区,每个分区专属于一个子分区。硬件含义:
- 每个 Warp 的寄存器分配被限定在其所在子分区的 64KB 空间内,不存在跨分区寄存器访问。
- 每个 64KB 分区服务更少的 resident warp(~16 warp/子分区,相比 Kepler 的 ~64 warp 共享 256KB),降低了 RF bank conflict 概率。
- RF 分区的读/写端口数量可以针对子分区的访问模式独立优化,无需考虑全局端口的仲裁复杂性。
Operand Reuse Cache 的硬件实现
Operand Reuse Cache 位于 Operand Collector 和 Execution Unit 之间,是每线程的微型缓存(L5 推断:每线程 4-8 条目,每条目 32-bit)。工作流程:
- 编译器在指令的某个源操作数上标记
.reuse。 - 该指令执行时,结果写回 Register File 的同时,被额外复制到 Operand Reuse Cache 中。
- 后续指令如果读取同一寄存器且标记匹配,Operand Collector 优先从 Reuse Cache 读取,不发起到 RF 的读请求。
- Reuse Cache 采用简单的寄存器号匹配逻辑,若后续指令读取不同的寄存器号,则新值覆盖旧值。
Reuse Cache 的容量有限,编译器的 .reuse 标记策略需要判断哪些操作数最有可能在短期内被复用。通常,累加器变量、循环迭代变量、频繁读取的常量地址等是 .reuse 的最佳候选。
最大并发 Thread Block 数提升
Maxwell 将每个 SM 支持的最大并发 Thread Block 数从 Kepler 的 16 提高到 32。实际意义:
- 对于使用较少寄存器/Shared Memory 的小 thread block(如 64 或 128 线程/block),Maxwell 可以同时驻留更多 block,增加 eligible warp 的池子大小。
- 更多的 concurrent block 意味着当某个 block 的所有 warp 都因访存延迟而停顿时,其他 block 的 warp 可以填补执行间隙,提升执行单元利用率。
- 但并发 block 数的提升受限于 RF 和 Shared Memory 的实际容量:若每个 block 使用大量寄存器,32 block/SM 的理论上限无法达到。Occupancy 的实际值由编译器报告的寄存器用量、block size 和 Shared Memory 用量共同决定。
4.4.2 Pascal:维持设计与溢出路径优化
Pascal 的 Register File 容量和分区结构与 Maxwell 保持一致:每 SM 64K 32-bit 寄存器(256KB),GP10x 四分区、GP100 双分区。
Local Memory 可缓存 L1
Pascal 的一项重要改进是允许 Local Memory(寄存器溢出空间)的数据被缓存在 L1 Cache 中。Maxwell 中,Local Memory 访问绕过 L1,直接发往 L2 或 device memory,寄存器溢出的延迟惩罚很高(数百周期)。
Pascal 的变更:
- 当编译器因寄存器压力将变量溢出到 Local Memory 时,LD/ST Unit 的加载请求会先查询 L1 Cache。
- 若 L1 hit,溢出数据的访问延迟降至 L1 访问级别(~20-40 周期),远低于 L2/device memory。
- 若 L1 miss,数据从 L2 或 device memory 取回时会被填入 L1,供后续溢出访问复用。
实际影响:开发者和编译器在寄存器分配上有了更大的权衡空间。在 Maxwell 上,register spill 是需要极力避免的高代价事件。在 Pascal 上,适度的 spill(特别是具有时间局部性的 spill)对性能的冲击被明显缓和。使用大量寄存器的复杂 kernel 在 Pascal 上可以在不牺牲太多性能的情况下维持更高的 Occupancy。
4.5 Memory Subsystem
4.5.1 Maxwell:缓存重构与带宽优化
Maxwell 的内存子系统围绕两个变化展开:Shared Memory 的独立化,以及 L1/Texture Cache 的合并。
Shared Memory 独立专用存储
Maxwell 为每个 SMM 配备了独立的 Shared Memory SRAM,不再与 L1 Cache 共享可配置的 SRAM 池。GM107 每 SMM 64KB,GM204 每 SMM 96KB。
与 Fermi/Kepler 的 L1/Shared 可配置分割(16/48KB 或 48/16KB)相比,变化在于:
- 硬件层面不再有 L1/Shared Memory 的分割逻辑,SRAM 池被物理划分为两个独立部分。
- Shared Memory 容量固定,开发者不能再通过
cudaFuncSetCacheConfig()等 API 将 Shared Memory 空间交换给 L1 Cache 使用。 - L1 Cache 的容量也固定(L5 推断:每子分区 12-24KB,总计 48-96KB/SMM),不受 Shared Memory 使用量的影响。
工程逻辑:Maxwell 的四象限设计中每个子分区需要独立的 Shared Memory 和 L1 Cache,可配置分割的灵活性带来额外的控制逻辑和布线复杂度。将两者固定分配后,控制逻辑简化,时序收敛更容易。
L1/Texture Cache 合并
Maxwell 将 L1 Cache 和 Texture Cache 合并为统一的 L1/Texture Cache。在 Kepler 中,L1 Cache 和 Texture Cache 是两个独立的缓存结构,分别服务于 generic load/store 和 texture sampling。Maxwell 的合并意味着:
- 只读 generic load(通过
__ldg()intrinsic)可以被路由到 L1/Texture Cache,享受 Texture Cache 的高带宽和特殊的缓存策略(如 non-coherent cache line 分配)。 - Texture sampling 请求和
__ldg()加载请求共享同一缓存资源,可能在带宽上产生竞争。 - 可写 load 和普通 store 请求仍然绕过 L1/Texture Cache,直接发往 L2(因 L1/Texture Cache 不保证写一致性)。
__ldg()** 只读加载路径**
__ldg() (load global via read-only data cache) 是 Maxwell 引入的显式缓存控制机制。其数据路径:
- Global Memory 地址 → LD/ST Unit → L1/Texture Cache →(miss 时)L2 Cache → Device Memory
- 与普通 load 路径(绕过 L1,直接到 L2)相比,
__ldg()利用了 L1/Texture Cache 的额外缓存层,对于具有空间局部性但缺乏时间局部性的只读数据(如查找表、常量参数),可以避免 L2 的污染并降低访问延迟。
编译器也可以通过 const __restrict__ 指针修饰符自动推断只读属性,将普通 global load 转换为 __ldg() 路径。
Delta Color Compression (DCC)
Maxwell 引入了改进的 Delta Color Compression,降低显存带宽压力。工作方式:
- 帧缓冲数据和纹理数据在写入显存前,由 Color Compression Engine 进行压缩。
- 压缩基于相邻像素的颜色差异(delta)而非绝对值,对于颜色渐变平滑的图像区域(如天空、水面),压缩率可达 2:1 至 8:1。
- 数据从显存读回时由 Decompression Engine 解压,对 SM 透明。
- DCC 仅在图形渲染路径中有效,对 compute kernel 的 generic memory access 不可见。
DCC 的有效带宽增益取决于场景内容的可压缩性。高对比度、高噪声场景压缩率低,DCC 收益有限。
显存接口
- GM204(GTX 980/980 Ti):256-bit GDDR5,带宽 ~224 GB/s
- GM200(Titan X):384-bit GDDR5,带宽 ~336 GB/s
4.5.2 Pascal:产品线的内存分化
Pascal 的内存子系统沿产品线出现了根本性分化:GP100 采用 HBM2,GP10x 沿用 GDDR5X。
GP100:HBM2 与 NVLink
GP100 是 NVIDIA 首批采用 HBM2 (High-Bandwidth Memory 2) 的 GPU:
- HBM2 接口:通过 3D 堆叠 DRAM 和 4096-bit 超宽内存总线,GP100 实现了 732 GB/s 的显存带宽,是 Maxwell Titan X (~336 GB/s) 的 2.2 倍。
- HBM2 的硬件实现:HBM2 通过硅中介层 (silicon interposer) 将多个 DRAM die 堆叠在 GPU die 旁边,通过高密度 Through-Silicon Vias (TSV) 连接。这种封装方式缩短了信号传输距离,降低了每 bit 的功耗,但封装成本远高于传统 GDDR5/X 的 PCB 布线方案。
- NVLink:GP100 集成了 NVLink 接口,第一代 NVLink 提供 160 GB/s 的双向带宽(单链路 20 GB/s × 8 链路),是 PCIe 3.0 x16 (~32 GB/s 双向) 的 5 倍。NVLink 使多个 GP100 可以直接点对点通信,绕过 CPU 和 PCIe 交换 fabric。在多 GPU 训练场景下,模型梯度通过 NVLink 聚合,减少了通信瓶颈。
732 GB/s 这个数字在 NVIDIA 官方的架构解析中有据可查。NVIDIA 官方博客 Inside Pascal 给出的规格表写明:GP100 集成 8 个 512-bit 内存控制器、合计 4096-bit 总线,Tesla P100 的显存带宽即为 732 GB/s。同一份资料还确认了 GP100 SM 的双分区构成:64 个 FP32 CUDA Core 与 32 个 FP64 单元,切分为两个 processing block,每个 block 含 32 个 FP32 Core、一个 Warp Scheduler 和两个 Dispatch Unit,与 4.3.2 节对 GP100 双分区重构的分析一致。
GP10x:GDDR5X
GP104(GTX 1080)因成本考量继续使用 GDDR5X:
- GDDR5X 将单 pin 数据速率从 GDDR5 的 7 Gbps 提升至 10-11 Gbps,GP104 的 256-bit 接口实现了 ~320 GB/s 带宽,接近 Maxwell GM200 的 384-bit GDDR5 水平。
- GDDR5X 的改进主要在 I/O 电路(四相数据采样而非 GDDR5 的两相),对 SM 内部的 memory hierarchy 无直接影响。
- GDDR5X 的功耗高于 HBM2,但封装成本远低于 HBM2 的硅中介层方案。
Pascal Unified Memory:Page Fault On-Demand Migration 硬件化
Pascal 在 GP100 上实现了 Unified Memory 的硬件级 Page Fault 和 On-Demand Page Migration:
- 当 GPU 访问一个当前不在其本地显存中的页面时,Memory Management Unit (MMU) 触发 Page Fault。
- Page Fault 被驱动程序捕获,驱动通过 NVLink 或 PCIe 将所需页面从 CPU 主存(或其他 GPU 的显存)迁移到当前 GPU 的显存。
- 页面迁移完成后,GPU 的页表被更新,访问请求重试。
- 这一机制将 Kepler/Maxwell 时代由软件显式管理的
cudaMemcpy操作,转变为硬件驱动的按需迁移,简化了编程模型。
硬件化 Page Fault 的隐性代价:首次访问远程页面的延迟极高(数百至数千微秒,取决于页面大小和互联带宽),对访存局部性差的 kernel,频繁的 page fault 会导致严重性能下降。Unified Memory 的性能接近显式管理的前提是:工作集的访问模式具有良好的局部性,且大部分数据在 kernel 启动前已预取到本地显存。
GP10x 的 Unified Memory 支持
GP104 同样支持 Pascal 级别的 Unified Memory(Page Fault On-Demand Migration),但其实际效用受限于 PCIe 带宽(无 NVLink)。CPU-GPU 页面迁移通过 PCIe 3.0 x16 进行,迁移带宽远低于 GP100 的 NVLink 路径。
4.6 Function Feature
4.6.1 Maxwell:Unified Memory 软件模型
Maxwell 时代(CUDA 6)引入了 Unified Memory 的早期软件模型。该模型在编程接口层面提供了 CPU/GPU 共享虚拟地址空间,底层仍依赖驱动程序在 cudaLaunchKernel 前后进行隐式的页面迁移和数据同步。 coherence 需要开发者手动维护(通过 cudaDeviceSynchronize 等同步原语)。
该软件模型为 Pascal 的硬件化 Page Fault 机制提供了编程模型原型,但 Maxwell 上的实际性能与显式 cudaMemcpy 相当或略差,因为驱动级别的隐式迁移缺乏应用层的访存信息,无法做到精确的预取和重叠。
4.6.2 Pascal:产品线的功能分化
GP100 的系统级功能
- NVLink 远程原子操作:GP100 通过 NVLink 支持对远程 GPU 显存的原子操作,为多 GPU 协同计算提供了低延迟同步手段。GP10x 不支持该功能。
- Compute Instruction-level Preemption:如 4.2.2 节所述,面向数据中心多租户调度。
GP10x 的图形与 VR 功能
- Simultaneous Multi-Projection (SMP):SMP 是 Pascal 为 VR 渲染效率引入的图形固定功能。传统渲染中,为 VR 的左右眼生成两个视角需要两次完整的几何遍历。SMP 允许在单次几何遍历中,通过硬件投影单元同时生成多个视角的图像。
- SMP 的硬件定位:SMP 是图形前端(Geometry/Tesselation/Rasterization 管线之前)的固定功能硬件,属于 PolyMorph Engine 和 Viewport Projection 单元的扩展,不是 SM 的本体改造。SMP 单元位于 GPC 层面,在顶点数据进入 SM 进行 shading 之前完成多视角投影。SM 内部的 CUDA Core、Warp Scheduler、Register File 等不受 SMP 影响。
- SMP 的硬件实现涉及额外的 viewport transform 矩阵存储和投影管线复制,对 SM 层面的 workload 没有直接影响。开发者通过 VRWorks API 调用 SMP 功能时,SM 看到的仍然是标准的光栅化任务,只是输入的图元已经被 SMP 单元预处理为多视角形式。
面向 AI 的低精度计算
- GP100 的 FP16
half2运算(4.1.2 节)为训练场景提供了 2x FP32 的吞吐率。 - GP10x 的 INT8
__dp4a运算(4.1.2 节)为推理场景提供了 4x FP32 的吞吐率。 - 两条产品线在 AI 精度上的差异化配置,反映了 Pascal 时代 NVIDIA 对训练/推理两条赛道的初步布局。
4.7 小结
主要设计权衡
静态调度的取舍
Maxwell-Pascal 坚定地选择了编译器驱动的静态调度(SCHI + 精简 Scoreboard),以牺牲硬件运行时的调度灵活性为代价换取三个收益:(1) Warp Scheduler 的硬件简化和功耗降低。(2) 四象限/双分区 SM 的物理隔离和时序收紧。(3) 编译器对指令级并行度的精确控制。代价:对于编译器难以静态分析的延迟场景(如不可预测的 pointer-chasing memory access),静态调度无法像动态调度那样在运行时自适应调整,可能导致执行单元空闲。
SM 分区化的演进
Maxwell 的四象限设计将 SM 拆分为四个最小可调度单元,每个单元 32 Core + 1 Scheduler,实现了极致的模块化和时序优化。Pascal GP10x 继承了这一设计,因为图形负载对 FP32 吞吐的偏好与 Maxwell 的设计目标一致。GP100 为容纳 FP64 单元而将 SM 重构为双分区,每 SM 的 Scheduler 数量减半,但通过堆叠更多 SM(60 个)补偿。两条路线的选择取决于目标市场对 FP64/FP32 面积比和单 SM 发射带宽的优先级排序。
内存接口的产品线分化
Pascal 在内存子系统上的产品线分化(HBM2 vs. GDDR5X、NVLink vs. PCIe)体现了"不计成本追求带宽"与"成本敏感务实平衡"的两极策略。GP100 的 HBM2 + NVLink 组合为数据中心提供了当时最高的单芯片带宽和多芯片互联能力,但封装和系统成本极高。GP10x 的 GDDR5X 方案在成本可控的前提下实现了带宽的适度提升,足以满足图形和游戏负载的需求。
开发者启示
- SCHI 的可见性:虽然开发者不直接编写 SASS,但理解 SCHI 的工作方式有助于解释某些编译器优化行为。例如,
__launch_bounds__和寄存器用量直接影响编译器生成的 Stall Count 和 WarpYield 模式,进而影响 Occupancy 和实际 IPC。 - Operand Reuse 的编译器 hint:虽然
.reuse标记由编译器自动插入,但开发者可以通过保持操作数在短指令序列中的复用模式(避免过度的寄存器重命名),帮助编译器生成命中率更高的 Reuse Cache 利用模式。 - 产品线差异的代码影响:为 GP100 编写的 FP16
half2代码无法在 GP10x 上运行(GP10x 不支持原生 FP16 CUDA Core 路径)。为 GP10x 编写的__dp4aINT8 代码在 GP100 上需回退到软件模拟。跨 Pascal 产品线的代码需要针对精度支持进行条件编译。 - Unified Memory 的局部性要求:Pascal 的 On-Demand Page Migration 简化了编程模型,但首次访问远程页面的延迟极高。开发者仍需通过数据预取、访存模式优化等手段确保良好的局部性,否则硬件 Page Fault 可能成为性能陷阱。
- Register Spill 的容忍度提升:Pascal 允许 Local Memory 缓存在 L1 中,使得适度的 register spill 不再像 Maxwell 那样致命。开发者可以在 Occupancy 和 register footprint 之间做更宽松的权衡,但仍需通过
nvcc -Xptxas -v监控 spill 量。
五、Volta - Turing 架构演进 (2017–2019)
Maxwell-Pascal 把调度负担交给编译器。SCHI 与精简 Scoreboard 换来了功耗与面积收益,但静态调度只回答了"发射时机"问题,Warp 内 32 条线程共享 PC 的锁步模型仍是执行侧的硬约束:分支发散串行化、单线程停顿拖住整个 Warp。Pascal 的 half2 与 __dp4a 低精度路径同时暴露出矩阵乘法在通用 ALU 上的低效。Volta 的回应是把 SIMT 的最小调度单元从 Warp 降到线程(Independent Thread Scheduling),并用第一代 Tensor Core 将矩阵乘从 CUDA Core 剥离。Turing 在这副骨架上补齐了图形侧的 Uniform Data Path 与 RT Core。Maxwell 四象限 SM 的寄存器分区策略在 Volta 的 256 KB RF 中被保留,但 ITS 的逐线程 Context 开销对 Occupancy 构成新压力。
5.1 ISA
Volta:Independent Thread Scheduling 与 128-bit 定长指令
Volta 之前,一个 Warp 内 32 个线程共享同一个 Program Counter。分支发散时,硬件通过 Execution Mask 和 Call Stack 将不同路径串行化,即使只有一条线程走了慢路径,其余 31 条线程也要等待。更隐蔽的问题:Pascal 及更早架构中 Warp 内线程无法细粒度同步。一个线程因等待 Mutex 或屏障而停顿时,整个 Warp 都被拖住,因为硬件没有独立追踪每条线程执行状态的机制。
Volta 的 Independent Thread Scheduling (ITS) 为每个线程分配了独立的 PC 和 Call Stack。Warp Scheduler 不再以 Warp 为最小调度粒度,而是以单个线程为粒度决定暂停与恢复。同一 Warp 中不同分支路径的指令可以交织执行:路径 A 的线程发射后,路径 B 的线程无需等待路径 A 全部完成即可在后续周期发射。稀疏控制流负载中的有效 Issue Rate 因此更接近理论值。
但 ITS 并非 CPU 式的乱序执行。Volta 的指令发射仍然顺序进行,Warp Scheduler 在 ready warp 之间做选择,被选中的 warp 内的指令按 PC 顺序发射。Warp 内线程的并发原语(如 __syncwarp())仍需开发者显式插入,硬件不会自动 reconverge。ITS 的代价:每个线程需要额外存储 PC 和 Call Stack 状态,由专用硬件管理,不占用 Register File。
为配合 ITS,Volta 将指令格式改为固定的 128-bit 定长编码。Maxwell/Pascal 采用"三条指令 + 一条控制字"的打包方式(每 4 条指令中第 4 条为 SASS Control Code),编译器在该控制字中显式指定发射延迟、依赖屏障等调度信息。Volta 则将 Scoreboard 依赖延迟、Yield 标志等控制字段直接嵌入每条 128-bit 指令内部。硬件 Decode 阶段无需跨指令边界读取独立的控制字即可获取完整的调度信息,简化了 L0 I-Cache 的取指路径。
128-bit 定长格式的副作用是指令 footprint 增大,每条指令从 64-bit(平均)增至 128-bit,在相同 I-Cache 容量下命中率下降。Volta 通过在每个 SM Partition 内引入 L0 I-Cache(取代此前架构的指令 Buffer)来缓解这一问题。L0 I-Cache 缓存当前在该分区上活跃 Warp 的热点指令,在 ITS 导致各线程执行路径发散时,减少了对 Shared L1 I-Cache 的访问压力。
ISA 层面,Volta 引入了 HMMA (Half-Precision Matrix Multiply-Accumulate) 指令,驱动第一代 Tensor Core。HMMA 指令在一次操作中完成 4×4 FP16 矩阵乘法并以 FP32 累加至输出矩阵。ISA 还新增了 MATCH、BAR.RED 等 Warp 级同步指令,允许开发者显式控制 Warp Reconvergence,替代早期架构中依赖隐式同步假设的编程模型。
ITS 开启后,包含复杂分支发散的 Kernel 的 IPC 可能提升 10%–30%,但同一 Warp 内线程的 __syncwarp() 缺失将导致数据竞争。这在 Pascal 上可能因隐式收敛而侥幸通过,在 Volta 上必定暴露。
Turing:Uniform Data Path 与 ISA 扩展
Turing 完整继承了 Volta 的 128-bit 定长指令格式和 ITS 模型,Compute Capability 7.5 的 SASS 在调度控制字段的编码上与 Volta 保持一致。Turing 的 ISA 扩展集中在三个方向:
第一,Uniform Register File 与 Uniform Data Path。图形 Shader 中存在大量跨 Warp 所有线程保持恒定的 Uniform 变量(如模型矩阵、光源参数)。以往架构中,每个线程各自从 Constant Cache 读取并占用独立的寄存器槽位。Turing 在 SM Partition 内增加了一组标量寄存器和独立的读取端口,Uniform 变量仅需存储一份,Warp 内所有线程通过 Uniform Data Path 只读访问。Uniform Data Path 还可以加速 Warp-uniform 的分支判断:当硬件检测到 Warp 内所有线程走同一路径时,条件计算由标量路径执行一次并广播结果,避免 32 条线程重复执行相同的标量运算。地址计算是这条标量路径最典型的受益者:Warp-uniform 的基址与偏移运算由标量 ALU 执行一次并广播,地址生成与 32-lane 的浮点数据通路在硬件上解耦。Uniform RF 对 CUDA 开发者透明,由编译器自动检测并分配。
第二,Tensor Core 指令扩展。第二代 Tensor Core 新增了 INT8 和 INT4 矩阵乘加模式,ISA 相应扩展了 IMMA (Integer Matrix Multiply-Accumulate) 指令族。
第三,RT Core 驱动指令。Turing 引入了与 BVH 遍历、光线-三角形求交相关的专用指令,由驱动和 API 层封装,开发者通过 DXR/Vulkan RT API 调用。
这三条扩展中,Uniform Data Path 的长期影响最容易被低估:它表面上是寄存器分配与取数路径的优化,实质是地址与数据在硬件上的分工被重新划定。
Uniform Data Path 是 Turing 全部 ISA 扩展中影响最久远的一项,因为它触碰的是内存模型本身。地址计算从 32-lane 数据通路剥离之后,剩余工作只是工程收尾:Blackwell 的 IMAD.WIDE 把 64-bit 地址生成压进单条指令,SASS 的全局内存访问定型为 LDG.E 配平坦 64-bit 虚拟地址的形式,一条指令、一个寄存器对中的指针、一次 TLB 翻译。Turing 同期把 LD/ST Unit 从每 SM 4 个翻倍至 8 个,说明厂商很清楚全局加载的供给压力会持续上升。通用逻辑寻址在现代硬件上不是稀缺资源,而是标配。
把这一事实摆在旁边,高层图形 API 的资源绑定模型显得格外沉重。CPU 侧录制、运行期频繁切换的巨型 Descriptor 结构,是早期 GPU 缺乏通用逻辑寻址时留下的代偿:纹理与 buffer 只能走固定功能的纹理寻址路径,API 必须替硬件维护一张资源表,并在每次 Draw 之间搬运它。今天的指令层里,一次资源访问早已退化为对某个基址的 LDG 指针操作;Descriptor Heap 对 SM 而言只是显存中另一个待加载的指针数据源。绑定模型所管理的大部分状态,硬件并不需要;其巨型且不透明的形态同时推高了 CPU 侧的录制与切换成本。
但纯 Bindless 的代价同样需要用机制说话。Bindless 把每次资源访问变成索引 → descriptor cache 查询 → 间接寻址的链式依赖。working set 小、索引分布均匀时,这条链被缓存掩盖;working set 超出 descriptor cache 的覆盖能力,或 shader 中出现不规则稀疏索引时,Warp 内 32 条线程命中 32 个不同的资源描述符,divergent resource indexing 直接破坏 descriptor cache 的局部性。与数据加载不同,描述符加载位于每次资源访问的关键路径上,它的 miss 会反向阻塞所有依赖该资源的后续 LDG;TLB miss 与 page walk 的长尾延迟层层叠加,SM 端表现为数百周期量级、可被性能计数器直接观察的零利用率停顿。吞吐的稳定性比寻址的自由度更稀缺。
结论与主流偏好相反:支持细粒度局部控制、避免无节制 indirection 的 Descriptor Table 模型,在现代高并发引擎设计中更具实际工程价值。物理上,table 把每个绘制批次的资源 working set 显式约束在可预测的范围内,descriptor cache 与 TLB 的行为因此可分析、可复现;工程上,table 的内容在录制期可见、可快照、可回放,RHI 层的调试确定性远高于一个被全引擎共享、逐帧改写的全局描述符数组。绑定状态该以什么粒度保留、保留在硬件可见的哪种结构里,与同步语义、几何调度一起构成系列终章的核心问题。
5.2 Scheduling
Volta:Single-Issue、SM Partition 与三层调度体系
Volta 每个 SM 被划分为 4 个 Partition(也称 Processing Block),每个 Partition 配备一个专用的 Warp Scheduler 和单条 Issue Slot。须区分三个层级:scheduler issue 模型、execution datapath 模型、SM aggregate throughput 模型。
Volta 的 sub-partition scheduler 从控制逻辑角度看不是 CPU 式乱序双发射器,每个 scheduler 每周期选择一条 warp instruction 发射。但 Volta 同时引入独立 FP32 与 INT32 execution resources,使整数地址计算、loop counter、pointer arithmetic 等操作可以与 FP32 arithmetic 在 SM 吞吐层面重叠。官方所谓 simultaneous FP32/INT32 execution 应理解为执行资源并行,即独立 FP32 与 INT32 datapath 可在 SM 层面同时保持 busy(来自不同 warp、经不同 scheduler issue),而不是保证单个 warp scheduler 在同一周期发射一条 FP 指令和一条 INT 指令。
这一设计的工程含义:Volta 将"scheduler 控制逻辑"与"execution datapath 并行"拆开。在足够 eligible warp、无 scoreboard/RF/operand conflict、且指令 mix 合适时,不同 Partition 可以分别将 FP 和 INT 指令送入各自独立的 datapath,实现 SM aggregate throughput 层面的并行。
取指路径上,每个 Partition 内的 L0 I-Cache 服务该 Partition 上活跃 Warp 的指令供给。L0 I-Cache 命中时,取指延迟低于访问 SM 级 Shared L1 I-Cache。未命中时回退到 L1。在 ITS 导致 Warp 内线程执行路径发散的场景下,L0 I-Cache 减少了跨 Partition 的取指竞争。
Volta/Turing 的调度体系可从三个层次理解:
- Grid 级:GigaThread Engine 将 Grid 拆分为 Thread Block,分配到各 GPC 的 SM 上,关注 SM 资源利用率与负载均衡。
- SM 级:每个 SM 支持 64 个并发 Warp(Volta)或 32 个(Turing),Warp 被分配到 4 个 Partition 上,每个 Partition 的 Warp Scheduler 管理 16 个(Volta)或 8 个(Turing)Warp。
- Partition 级:Warp Scheduler 从本 Partition 的 ready warp 中选出一条指令,经 Scoreboard 依赖检查后发射到执行单元。ITS 允许 Scheduler 以线程粒度处理发散,但发射粒度仍是 warp。
Volta 每 SM 64 Warp 的并发容量意味着在寄存器用量为 48/thread(即每 Warp 占用 1.5 KB,64 Warp 共 96 KB)时仍可满 Occupancy。超过此寄存器压力,Occupancy 下降将导致 latency hiding 能力减弱。
Turing:FP32 与 INT32 并发执行
Turing 延续 Volta 的独立 FP32/INT32 datapath,并把这一点面向图形 shader 中常见的 FP arithmetic + integer address/control mix 进行优化。公开资料能支撑 execution resource 层面的并行(独立 FP32 与 INT32 datapath 在足够 eligible warp 供给下可同时工作),具体的 warp 级发射机制(是否固定来自两个不同 warp、是否涉及 partition 协调)属于未公开的微架构实现。
这一保留设计的收益场景:典型图形负载中,shader 经常同时产生 FP arithmetic 和 integer address/control 指令。独立 datapath 保证 INT 操作不抢占 FP Pipeline,当 warp scheduler 能持续供给 eligible warp 时,SM aggregate throughput 可同时覆盖两类操作。
以指针追逐或索引计算为主的 Kernel(如图遍历、哈希表),在 Turing 上的 IPC 通常高于 Volta 10%–20%,前提是有足够的 Warp-level parallelism 供 scheduler 持续选出 ready warp。
5.3 Execution Unit
Volta:SM Partition、独立 INT32 管线与第一代 Tensor Core
Volta GV100 每个 SM 划分为 4 个 Partition,每 Partition 的资源配置为:
- 16 FP32 CUDA Core
- 8 FP64 CUDA Core(仅 GV100 完整配置,消费级 SKU 削减)
- 16 INT32 ALU
- 2 Tensor Core
- 1 Warp Scheduler / 1 Issue Slot
- 64 KB Register File 分区
- L0 I-Cache
SM 总计:64 FP32 + 32 FP64 + 64 INT32 + 8 Tensor Core。
独立 INT32 管线的意义:Pascal 及更早架构中,INT32 操作与 FP32 共享执行管线,整数运算会占用 FP32 执行资源,导致后续 FP 指令等待。Volta 为 INT32 配置了完全独立的执行单元和写回路径。独立 datapath 的含义是:FP32 与 INT32 operations 可在 SM 内部并行执行、独立写回,在指令 mix 合适且 warp scheduler 供给充分的条件下,SM aggregate throughput 可同时覆盖 FP32 和 INT32 operations。这一分离使后续架构得以维持并发执行能力。但这不是单个 warp scheduler 的 dual-issue,每个 scheduler 每周期仍选择一条 warp instruction。
第一代 Tensor Core:每个 Tensor Core 在每个时钟周期可执行 64 次 FMA 运算,等效于一次 4×4 FP16 矩阵乘并以 FP32 累加。8 个 Tensor Core 的总吞吐使得 Volta 的混合精度峰值算力达到同代 FP32 峰值的 8 倍。Tensor Core 由专门的 HMMA 指令触发,其执行过程与常规 ALU Pipeline 不共享 datapath,不会阻塞 CUDA Core 的发射。Operand 来自 Register File,结果写回 Register File,Scoreboard 独立追踪 Tensor Core 指令的完成状态。
深入到内部结构,Tensor Core 的运算层次自底向上分为四级。Warp 的 32 个线程被划分为 8 个 thread group,每 group 4 个线程,寄存器在 thread group 内部互相可见,这是硬件数据共享的最小粒度。最底层运算原语是 FEDP(Four-Element Dot-Product),单周期完成一次 1×4 与 4×1 向量点积并累加到 FP32 结果寄存器。每个 thread group 配置 4 个 FEDP 单元。向上一级,两个 thread group 构成一个 Octet。再向上,两个 Octet 构成一个完整 Tensor Core,合计 4×4×2×2 = 64 个并行乘法单元,对应每周期 4×4×4 = 64 FMA 的峰值吞吐。
Octet 内部的数据流做了显式共享优化:同一 Octet 的两个 thread group(例如 TG0 与 TG4)共用 matrix B buffer,A 矩阵则由 thread0 加载后广播至组内其余线程。这一设计将寄存器读端口压力约束在 thread group 粒度,规避了 32 线程全局广播的物理布线代价。两个 Octet 之间无数据依赖,可完全独立并行执行,硬件上不存在跨 Octet 的同步开销。
SASS 层面,一条逻辑上的 16×16×16 混合精度 MMA 被编译器展开为 16 条 HMMA 指令,分发到 8 个 thread group 逐步推进。实测首条指令延迟约 10 cycle,包含操作数收集与 pipeline fill 的启动代价。后续每条约 2 cycle 流水发射,16 条指令总耗时约 54 cycle。这组数据揭示了 Tensor Core pipeline 的关键特征:流水级数深、首次启动代价高,但一旦填满后吞吐接近峰值,连续 MMA 调用可有效摊薄 pipeline bubble。对内核开发者而言,保持 HMMA 指令连续发射、避免中间插入标量依赖链,是榨取 Tensor Core 利用率的首要原则。
FP64 配置:GV100 维持 FP32:FP64 = 2:1 的比例,延续了 GP100 的 HPC 导向配置。但这一比例仅限数据中心芯片,消费级 Volta SKU(如 Titan V 的后续版本)FP64 单元被削减。
Turing:TPC 重组、RT Core 与第二代 Tensor Core
Turing TU102 的 SM 资源配置有所调整:
- 64 FP32 CUDA Core
- 64 INT32 ALU(独立管线)
- 0 FP64 CUDA Core(消费级芯片完全移除)
- 8 Tensor Core(第二代)
- 1 RT Core 每 SM
- LD/ST Unit 从 Pascal 的每 SM 4 个增至 8 个
SM 总量较 Volta 有所缩减,但 TPC 包含的 SM 数从 1 个增至 2 个,通过增加 TPC/SM 总数来维持整体吞吐。这种"小 SM、多 TPC"的组织方式提升了负载均衡的灵活性。
第二代 Tensor Core 在 Volta 的 FP16 基础上新增了对 INT8 和 INT4 矩阵运算的支持。INT8 的运算吞吐率为 FP16 的 2 倍,INT4 为 4 倍。这一扩展针对 AI 推理场景,低精度权重的矩阵乘法可在同等带宽下搬运更多参数。
第一代 RT Core 是 Turing 最重要的新增单元。每个 SM 配置 1 个 RT Core,硬件上包含两个功能模块:
- Box Intersection Engine:执行光线与 BVH 包围盒的相交测试,负责场景树遍历。
- Triangle Intersection Engine:执行光线与三角形的精确求交,返回交点坐标和重心坐标。
RT Core 与 CUDA Core / Tensor Core 并行工作,由专用指令触发。BVH 遍历的内存访问模式(随机跳转、不规则访存)对 L1/L2 Cache 造成很大压力,这也是 Turing 将 L2 容量维持 6 MB 并将 LD/ST Unit 翻倍的原因之一。
LD/ST Unit 倍增:从每 SM 4 个增至 8 个,直接提升了 Global/Local Memory 操作的并发度。配合 96 KB L1/Shared Memory 的统一存储,Turing 的访存吞吐能力较 Pascal 提升一倍。
5.4 Register File
Volta:256 KB 分区 RF 与 ITS 的上下文管理
Volta GV100 每个 SM 配置 256 KB Register File,被均匀划分为 4 个 64 KB Bank,每个 Bank 专属于一个 SM Partition。分区设计下每个 Warp Scheduler 仅访问本地 Bank,消除了跨分区寄存器读写的端口竞争,提高了并行访问带宽。
ITS 的引入对寄存器管理产生了间接影响。独立 PC 和 Call Stack 由专用硬件(非 Register File)维护,Warp Scheduler 需要追踪每个线程的执行状态,Scoreboard 的依赖追踪粒度因此需要适应线程级发散:当 Warp 内部分线程因依赖而停顿时,Scoreboard 必须精确标记哪些线程可以参与下一轮发射。Volta 的 Scoreboard 在 Pascal 基础上扩展了跟踪位宽,以记录线程级的 Write-after-Read 和 Read-after-Write 状态。
Operand Reuse 特性在 Volta 上延续:编译器通过 .reuse 标记将特定操作数缓存于小型 Reuse Buffer。当寄存器压力超过物理容量时发生 Spill,溢出数据存入 Local Memory。Volta 的统一 L1/Shared Memory 设计使 Local Memory 访问经过 L1 Cache,降低了 Spill 的延迟代价。
Turing:Uniform Register File 的引入
Turing 在保留 256 KB 常规 Register File(4×64 KB 分区)的基础上,每个 SM Partition 新增了 2 KB Uniform Register File,每 SM 共 8 KB(512 个 32-bit 寄存器)。
Uniform RF 用于存储 Warp-uniform 的数据:当一个 Warp 内 32 条线程都需要同一个值(如常量、循环边界、统一分支条件),编译器将该值存入 Uniform RF,Warp 内所有线程通过 Uniform Data Path 只读访问。这一机制的硬件意义在于:
- 减少常规 RF 占用:原本需要为 32 条线程各分配一个寄存器槽位的 uniform 值,现在只需一个 Uniform 寄存器。
- 降低 Constant Cache 压力:Uniform 变量不再需要从 Constant Cache 经 L1 读取,减少了访存事务。
- 标量运算节能:Warp-uniform 的算术运算可由 Uniform Data Path 上的标量 ALU 执行一次并广播,避免 32 条 SIMD 线程重复执行相同的标量操作。
Uniform RF 对 CUDA 开发者透明,由编译器在检测到 Warp-uniform 变量时自动分配。Scoreboard 和寄存器分配逻辑相应增强,以追踪 Uniform 数据的依赖关系。
包含大量 Uniform 变量(如矩阵变换参数批量传递)的 Shader,在 Turing 上的 Register Pressure 通常较 Volta 低 5%–15%。若编译器未能正确识别 Uniform 性(如通过指针间接访问的常量),Uniform RF 不会被利用,性能回归至 Volta 水平。
5.5 Memory Subsystem
Volta:L1/Shared Memory 统一、HBM2 与 NVLink 2.0
Volta 在每个 SM 中将 Shared Memory 与 L1 Data Cache 统一为同一片 128 KB 的片上存储。应用程序可在启动时动态配置划分比例:64 KB Shared + 64 KB L1,或 96 KB Shared + 32 KB L1。统一设计的硬件收益是 Shared Memory 和 L1 Cache 共享读写端口和 Tag/Status 存储,提高了端口利用率和面积效率。对 CUDA 开发者而言,Local Memory(寄存器溢出)访问自动经过 L1 Cache,不再像 Kepler/Maxwell 时代那样绕过 L1 直接访问 L2,Spill 延迟因此降低。
Stream Cache 与 TAG-MSHR 合并:
Volta 的 L1 在微架构层面被称为 stream cache,其设计目标与传统 CPU L1 存在本质差异。传统 cache 的 MSHR(Miss Status Holding Register)数量有限,当 outstanding miss 数超过 MSHR 容量时后续请求必须 stall。stream cache 则允许 unlimited misses in flight:miss 不阻塞后续访问,cache 仅在数据返回时才分配 cacheline 槽位(从架构行为推断)。这种设计适配了 GPU 数千线程并发访存、miss 率天然高的工作负载特征。
硬件实现上,Volta 大概率将传统的 TAG Array 与 MSHR 合并为统一的 TAG-MSHR Array。合并后每个 entry 既记录 cacheline 的 tag/valid/dirty 状态,也承担 pending miss 的地址匹配与请求合并功能。这种融合减少了单独 MSHR 查找的面积和延迟开销。Filling policy 我判断采用 on-fill 策略:响应数据从 L2 返回后才执行 victim eviction 并写入新数据,而非在 miss 发生时立即驱逐,避免了 evict 后请求被取消导致的无效驱逐。
L1 的写策略为 Write Eviction:write miss 时数据直写 L2 而不在 L1 分配 cacheline。write hit 时使命中的 cacheline 失效(invalidate)并将数据写通至 L2(这个行为实测可以确认)。这一策略保证了 L1 中不存在 dirty line,简化了一致性维护。L2 端采用 write-validate 策略:write miss 时不从显存 fetch 整条 cacheline,而是直接将数据写入并设置 write mask 标记有效字节。仅在 cacheline 被 evict 时,硬件才将 masked 数据与显存内容合并后写回(同样是测出来的),以此减少写路径上的读放大。
L2 Cache 容量扩展至 6 MB(GP100 为 4 MB),服务于 HPC 和深度学习训练中大规模数据集的缓存需求。更大的 L2 对重复数据的命中率提升有直接贡献,降低了对 HBM2 显存带宽的依赖。
Volta GV100 采用 HBM2 显存,带宽 900 GB/s。HBM2 通过 4096-bit 超宽总线实现了远超 GDDR5X 的带宽密度,为 Tensor Core 的矩阵运算提供了充足的数据供给。HBM2 的代价是更高的封装成本和更复杂的散热设计,这限制了 Volta 主要面向数据中心市场。
NVLink 2.0 支持最多 6 个链路,GPU 间双向通信带宽 300 GB/s。多 GPU 系统的显存池化和参数同步因 NVLink 2.0 不再受 PCIe 带宽约束,对于大模型分布式训练的扩展效率有决定性影响。
Turing:96 KB L1/Shared Memory、GDDR6 与 L2 维持
Turing 继承了 Volta 的 L1/Shared Memory 统一设计,但将每 SM 的总容量从 128 KB 调整为 96 KB,提供两种配置模式:
- 64 KB Shared Memory + 32 KB L1 Cache
- 32 KB Shared Memory + 64 KB L1 Cache
96 KB 的总容量较 Volta 的 128 KB 有所缩减,属 Turing SM 整体缩减策略的一部分。但对于消费级图形负载,96 KB 的 Shared Memory 上限通常足够:Turing 的单个 SM 并发 Warp 数从 Volta 的 64 降至 32,每 Warp 可用的 Shared Memory 配额反而更加充裕。
Turing TU102 维持 6 MB L2 Cache,与 GV100 持平,是 GP102(3 MB)的两倍。更大的 L2 对 RT Core 的 BVH 遍历和纹理采样直接相关:BVH 节点数据的不规则访问模式部分命中 L2,减少了对显存的随机访问。
Turing 是首个采用 GDDR6 显存的 GPU 架构。GDDR6 的 14 Gbps 速率将高端 SKU(RTX 2080 Ti)的显存带宽推至 600 GB/s 以上。GDDR6 的峰值带宽低于 Volta 的 HBM2(900 GB/s),但成本和功耗更具优势,使高带宽显存能够进入消费级产品。Turing 还引入了渲染目标无损压缩,等效提升了显存带宽利用效率。
需要 96 KB 以上 Shared Memory 的 CUDA Kernel(如大型矩阵块的共享缓存)在 Turing 上因容量限制需要调整算法分块大小(tile size),否则 Kernel 无法启动。Volta 的 128 KB 统一存储在此类场景下有更大的配置空间。
5.6 Function Feature
Graphics:Turing 的混合渲染管线
Volta 在图形功能上相对保守,主要继承 Pascal 的固定功能管线,包括 Simultaneous Multi-Projection (SMP) 等特性。Volta 的图形能力更多被视为 Pascal 的延续,其主要价值在于 HPC 和 AI 计算。
Turing 则引入了多项面向实时图形的硬件特性:
Mesh Shading 与 Task Shading:取代传统的固定功能几何处理管线。Mesh Shader 以 Compute-like 的编程模型灵活生成几何体,Task Shader 作为前置阶段控制 Mesh Shader 的启动粒度和 LOD 选择。这一组合消除了传统 Vertex Shader → Hull Shader → Domain Shader → Geometry Shader 管线的固定阶段限制,提高了小批量高复杂度几何场景的处理吞吐。
硬件层面的对应改动是几何装配职责的转移。传统管线中,顶点去重与图元装配由前端固定功能单元隐式完成,即自 Tesla 起便存在的 PolyMorph Engine 路径。Mesh 路径上,这些职责被移交给线程组:几何数据以小块簇(meshlet)的形式驻留在线程组私有的 Shared Memory 中,其驻留周期、去重与剔除全部由 shader 代码显式管理。Mesh Shader 因此复用的是 Compute 路径既有的 Shared Memory 与线程组调度设施,而非一条新增的专用几何流水线。
Task/Mesh Shader 不是编程模型升级,而是固定功能前端几何调度能力物理见顶后的承认。传统 DrawIndexed 管线的效率建立在两块隐式硬件之上:前端的 Index Deduplication 电路,与滑动窗口式的 Post-Transform Cache(PTC)。这套机制成立的前提是顶点重用落在滑窗容量之内:相同顶点在窗口内重复出现即命中去重,输入顺序友好时,落在窗口内的顶点只被着色一次。当几何密度推进到 Nanite 级别,三角形尺寸逼近像素、cluster 数量爆炸,顶点流在固定滑窗内的局部性消失,前端撞上滑窗覆盖率失效的断崖(Occupancy Cliff),隐式重用的收益归零,每个三角形被重复拾取的顶点数随网格密度同步上升。扩容滑窗无法修复这一问题:工作集按数量级增长,固定容量对它的覆盖率随之归零,局部性消失与容量不足在这里是同一件事。
硬件的对策是拆除而非扩容。Mesh 路径上不再存在隐式去重电路,Shared Memory 被直接暴露给线程组作为可编程缓冲:meshlet 的驻留、顶点去重、像素级精准剔除(Shader Culling)全部变成显式的 shader 代码,由 Warp Scheduler 按普通 compute warp 调度。这一转移的代价是重用率不再有硬件保底,未经充分优化的 mesh shader 可能慢于固定管线,Shared Memory 占用还要与 Occupancy 做显式权衡。换来的是剔除精度与调度粒度完全由引擎决定,去重算法可按 meshlet 拓扑定制,上限高于任何固定滑窗。几何调度从固定功能状态机退化为线程级问题,这正是它在 Vol.1 的公约数模型中本该具有的形态。
后果不止于微架构。传统 Draw 调用与 Retained-mode PSO 维系的隐式状态契约,前提正是前端存在一块执行 vertex fetch、去重与装配的固定功能硬件,管线状态才有被冻结进不可变对象的物理实体。当几何的生成与剔除都由一段 compute-like shader 显式完成,这块硬件实体消失,契约失去依据,Draw 语义与 PSO 模型的物理瓦解由此开始。这条线索与内存绑定模型、同步语义一起,构成系列终章的核心问题。
Variable Rate Shading (VRS):允许以低于像素频率的速率对画面非关键区域进行着色。硬件层面,Shading Rate 可以在 1×1、1×2、2×1、2×2 等粒度上逐 tile 配置,RT Core 输出的辅助信息可用于指导 VRS 的率选择。
Texture Space Shading:着色计算在对象的纹理空间而非屏幕空间完成,结果缓存到纹理中供后续采样重用。这一特性减少了对重复像素区域的冗余着色计算,提高了 Cache Locality。
DLSS (Deep Learning Super Sampling):通过 Tensor Core 加速的 AI 模型对低分辨率渲染图像进行超分辨率重建。DLSS 的推理负载完全运行在 Tensor Core 上,与同时进行的图形渲染(CUDA Core + RT Core)共享 SM 资源。Tensor Core 的 INT8 支持使 DLSS 的推理延迟足够低,能够融入实时渲染管线。
Compute:Tensor Core 驱动的 AI 加速
Volta 的第一代 Tensor Core 将混合精度矩阵乘法的硬件吞吐提升至 CUDA Core 的 8 倍,确立了 GPU 作为 AI 训练核心硬件的地位。第二代 NVLink(300 GB/s)支持的多 GPU 并行训练,使大模型分布式训练的参数同步瓶颈从互联带宽端得到缓解。
Turing 的第二代 Tensor Core 扩展至 INT8/INT4,使推理吞吐在同等功耗下进一步提升。DLSS 作为首个将 Tensor Core 融入实时图形管线的消费级应用,验证了"AI + 图形"混合工作负载的工程可行性。
5.7 小结
Volta-Turing 的核心变革是 Independent Thread Scheduling:在保持 warp-level 发射的框架下将调度的最小追踪单元从 Warp 降到线程,后续架构的异步拷贝和 Thread Block Cluster 建立在这一基础之上。Tensor Core 用可观的芯片面积换取矩阵乘法的专用吞吐,对不含密集矩阵运算的负载(分支发散严重的图算法等)无效;Volta 的 Single-Issue + 4 Partition 以 SM-level 并行调度替代 Partition-level 双发射,简化了 ITS 调度逻辑,代价是单 Warp ILP 较低,需要高 TLP 填充流水线。HBM2/GDDR6 的分化和 L1/Shared Memory 128KB/96KB 的总容量约束延续至后续架构。
调优层面需要注意:ITS 下 __syncwarp() 从建议变为必须,依赖隐式收敛的代码在 Volta+ 会产生数据竞争;Uniform RF 由编译器自动管理,__constant__ 声明更容易触发 Uniform 路径;RT Core 的 BVH 遍历有固定切换开销,小规模场景下纯 CUDA Core 软件路径可能更优。
六、Ampere – Ada (2020–2022)
Ampere (2020) 与 Ada (2022) 是 NVIDIA 两条产品线分支并行推进的两代架构。Ampere 的 GA100 (A100) 走数据中心路线,聚焦 Tensor Core HPC/AI 吞吐与多租户隔离。GA10x/GA102 (GeForce/RTX) 走图形路线,在 FP32 吞吐、RT Core、GDDR6X 与游戏图形管线上做差异化扩展。Ada (AD102/AD103/AD104) 则继承 GA10x 的图形/RTX 路线,通过 SER、大容量 L2、第四代 Tensor Core 与第三代 RT Core 将"neural graphics"推到消费级产品的前沿。
两条分支的硬件选择存在明确分野:GA100 的 SM 瘦身以容纳更多计算单元,牺牲图形管线换 HBM2 带宽与 MIG 隔离。GA10x 的 SM 保留完整图形能力,FP32 峰值翻倍。Ada 在 GA10x 的基础上继续扩展缓存层次与 RT 硬件,而不触及 SM 内 RF 容量与基本调度模型。理解这两代架构,关键是理解 NVIDIA 如何在同一代硅片工艺下,用不同的硬件资源配置策略服务于两个截然不同的市场。
6.1 ISA
Ampere ISA
Ampere 沿用了自 Volta 确立的 128-bit 定长 SASS 指令格式与 Independent Thread Scheduling (ITS) 模型。每条 SASS 指令携带 4-bit 谓词控制字段,warp scheduler 依据 per-thread predicate register 决定每个线程是否参与当前指令执行。ITS 的硬件含义已在 Volta/Turing 章节详细展开。Ampere 的继承并非简单延续,而是在 async copy / asynchronous barrier 等新硬件能力引入后,指令发射路径与依赖跟踪逻辑需要配合这些新原语进行扩展。
GA100 (Compute Capability 8.0) 与 GA10x (Compute Capability 8.6/8.9) 在 ISA 层面存在可观测差异:
- GA100 支持
cp.async系列指令与对应 async copy pipeline(从全局内存直接写入 shared memory,绕过 L1/RF),并暴露 asynchronous barrier (mbarrier) 原语。这些是面向 HPC/AI 训练负载的显存带宽优化手段:通过将数据搬运与计算在指令级解耦,减少因显式LDG → RF → STS路径造成的 register pressure 与中间数据污染。 - GA10x 同样支持 async copy 与 async barrier,但其 ISA 扩展重心偏向 RT Core 交互指令与稀疏 Tensor Core 操作码。Compute Capability 8.6/8.9 引入了针对 2:4 structured sparsity 的压缩矩阵加载指令,配合第三代 Tensor Core 的稀疏加速路径。
数据格式扩展是 Ampere ISA 层面的主要变化:
- TF32:并非独立的数据存储格式,而是一种 Tensor Core 内部的运算精度模式。其硬件含义为 8-bit 指数(与 FP32 一致)+ 10-bit 尾数(FP32 23-bit 尾数的截断),提供与 FP32 相当的动态范围,但将矩阵乘法内部的有效精度降至 19-bit。对于训练中的 matrix multiplication accumulate (MMA) 操作,TF32 在不改变权重/激活值存储格式的前提下,通过 Tensor Core 内部的精度截断提升单位面积 throughput。仅 GA100 的第三代 Tensor Core 完整支持 TF32,GA10x 同样支持,但该格式在图形线的设计目标更偏向 AI inference 与可编程着色中的计算密集型部分。
- BF16:Brain Float 16 格式(8-bit 指数 + 7-bit 尾数),由 Google 提出并在 Ampere 中引入硬件支持。相比 FP16(5-bit 指数 + 10-bit 尾数),BF16 以牺牲尾数精度换取与 FP32 一致的指数范围,减少了在混合精度训练中因指数下溢/上溢导致的数值不稳定问题。Ampere 的 Tensor Core 在 FP16 路径上复用部分硬件支持 BF16,但 ISA 层面需显式指定
.bf16修饰符以选择不同的尾数位宽与舍入行为。
Ada ISA
Ada (Compute Capability 8.9/9.0) 在 ISA 层面完全兼容 Ampere 的 SASS 指令集框架,确保已有 CUDA 二进制无需重编译即可运行。Ada 的 ISA 扩展集中在两条路径:
- 消费级 FP8 支持:第四代 Tensor Core 引入
E4M3(4-bit 指数 + 3-bit 尾数,近似动态范围 ±448)与E5M2(5-bit 指数 + 2-bit 尾数,动态范围 ±57344)两种 FP8 存储格式,以及对应的 MMA 操作码。这一扩展仅面向消费级/图形产品线(AD10x)。数据中心线的 FP8 训练支持由同期 Hopper (Compute Capability 9.0) 的 Transformer Engine 提供,两者的 FP8 硬件路径与软件暴露方式存在差异:Ada 的 FP8 主要用于 inference throughput 提升,Hopper 的 FP8 则配合 RND(随机舍入)与细粒度 scaling 支持训练场景。 - SER 硬件接口:Shader Execution Reordering 并非通过新增一组显式调度控制指令实现,而是通过硬件调度单元与 API 层(VK_KHR_shader_execution_reordering / DX12 Work Graphs)配合,对着色器 invocation 的执行顺序进行运行时重排。ISA 层面,Ada 增加了少量用于标记 reordering scope 与同步边界的控制指令,但具体的重排决策由硬件调度器根据 runtime locality 信息自主完成,不暴露给程序员细粒度控制。
6.2 Scheduling
Ampere 调度机制
Ampere 的 warp 调度模型继承 Volta/Turing 的 ITS 框架:每个 SM 配备 4 个 warp scheduler(GA100 与 GA10x 均为 4 scheduler/SM),每个 scheduler 每周期从分配给它的 warp 中选择一个 eligible warp 发射指令。ITS 允许 warp 内线程独立发散(per-thread PC),但指令发射粒度仍为 warp。scheduler 的仲裁逻辑基于 warp 状态(等待操作数、等待内存、等待 barrier、等待 scoreboard 等)选择就绪者。
GA10x SM 的调度路径:
GA10x/Ada 的四个 SM processing blocks 是对称的。每个 block/partition 包含一条 16-lane FP32-only datapath,以及一条 16-lane FP32-or-INT32 datapath。因此纯 FP32 时,两个 datapath 都可服务 FP32,形成 32 FP32 operations/partition/cycle。混合 FP32+INT32 时,该 partition 可形成 16 FP32 + 16 INT32 operations/cycle。四个 partition 合计为 128 FP32 operations/SM/cycle,或 64 FP32 + 64 INT32 operations/SM/cycle。这里描述的是 operations throughput,而不是保证每个 scheduler 每周期发射两条独立 warp 指令。实际 sustained throughput 仍取决于指令 mix、warp 就绪状态与 scheduler issue 能力。
GA100 SM 的调度差异:
GA100 面向数据中心的 SM 设计进行了"瘦身":每 SM 同样 4 scheduler,但 SM 内 CUDA Core 数量减少(64 FP32 / 32 FP64 / 64 INT32 / 32 Tensor Core),总 SM 数量增至 108(A100)以换取更高 aggregate throughput。GA100 的 FP64 比例(1:2 vs FP32)远高于 GA10x(1:64),这是数据中心 HPC workload 的直接反映。Scheduler 层面,GA100 增加了对 async copy pipeline 的独立跟踪逻辑:cp.async 指令发射后,对应的 memory transaction 与 shared memory write 在 async proxy 中完成,scheduler 无需等待 LDG→RF→STS 的全路径完成即可标记 warp 就绪,从而隐藏全局内存加载延迟。
Cooperative Groups 与 Async 原语:
Cooperative Groups 是 CUDA 编程模型对线程协作粒度 finer than thread block 的抽象。Ampere 为这一抽象提供的新硬件能力包括:
- Async Copy (
cp.async):从全局内存直接传输至 shared memory,绕过 L1 cache 与 register file。硬件路径为:LDG unit → async copy pipeline → shared memory bank。该路径减少了一次 RF 读写(传统路径:LDG → RF → STS),降低 register pressure,允许 compiler 分配更少寄存器用于临时数据缓冲。 - Asynchronous Barrier (
mbarrier):硬件实现的跨 warp 同步原语,替代软件__syncthreads()的显式计数逻辑。mbarrier在 shared memory 中维护到达计数,到达阈值后自动唤醒等待 warp,减少了因屏障同步造成的 scheduler yield/stop 开销。 - L2 Residency Controls:
cudaAccessPolicyWindow等机制允许软件提示 L2 cache 中某些地址范围的驻留优先级,硬件层面通过 L2 cache 的 way allocation / partition 逻辑实现。
Multi-Instance GPU (MIG) — GA100 独占:
MIG 是 GA100 (A100) 的数据中心线特性,GA10x 与 Ada 全系列均不支持。MIG 的硬件实现将 GA100 的 108 SM、HBM2 内存控制器、L2 cache、PCIe/NVLink 端口等资源按固定划分策略(1/2/3/4/7 GPU 实例)切分为多个硬件隔离的 compute instance。每个 instance 拥有独立的 GigaThread Engine 调度上下文、L2 cache slice 与内存带宽份额,在硬件层面实现故障隔离与 QoS 保证。驱动/OS 运行在 host 环境中,MIG instance 内部不运行完整的驱动栈。从开发者视角,一个 3g.40gb MIG instance 表现为一台独立的、Compute Capability 8.0 的 GPU,其 SM 数量、内存带宽与 L2 容量按比例缩减。
Ada 调度机制
Ada 在 Ampere 的 4-scheduler/4-block SM 模型基础上,引入 Shader Execution Reordering (SER)。SER 不同于 CPU 式的指令级乱序执行(OoO):SER 不改变单条指令在 warp 内的发射顺序,仅在更高粒度上对着色器 invocation(ray tracing 中的 shader call / hit group)的执行顺序进行重排,以提升 memory access locality 与 execution divergence 容忍度。
SER 的硬件机制:
RT Core 产生的 ray hit / intersection 结果到达 SM 后,传统执行模型按 ray 发射顺序依次调度对应的 hit shader。当 scene 中存在大量 incoherent ray(如反射/折射后的 secondary ray)时,相邻 ray 可能命中完全不同 geometry/material,导致 texture/sampler cache footprint 剧烈膨胀,SM occupancy 因 divergence 而下降。SER 的硬件实现引入了一个 reordering buffer(具体容量未公开),对到达的 shader invocation 按 material/geometry/locality key 进行重新分组,再 batch 提交给 warp scheduler 执行。
这一重排对硬件的影响:
- 寄存器压力:重排 buffer 需要保存待重排 invocation 的输入状态(hit attributes、ray payload 等),增加了有效 register footprint。若 shader 本身 register pressure 已高,SER 的额外状态可能反而降低 occupancy。
- Scoreboard 行为:重排后的 invocation 以新的顺序进入 warp scheduler,scoreboard 的 dependency tracking 需要处理乱序到达的 memory operation completion。
- 开发者可观察症状:SER 在 incoherent ray workload 中可降低 L1/L2 cache miss rate 5–20%(因 locality 改善),但在 highly coherent workload 中引入的 reordering latency 可能为负优化。NVIDIA NSight Graphics 可观测
Shader Execution Reordering指标,判断是否触发。
Ada 的 4-scheduler SM 模型与 Ampere GA10x 基本一致,scheduler 每周期仍从 eligible warp 中仲裁发射。SER 的重排逻辑位于 warp scheduler 之前(frontend / RT Core interface 层级),不替代 scheduler 本身的 issue arbitration。Ada 同样完整支持 Ampere 引入的 async copy 与 async barrier,且因 L2 容量增至 72 MB,async copy 的 effective latency hiding 窗口进一步扩大。
6.3 Execution Unit
Ampere SM 结构
GA10x (GeForce/RTX) SM
GA10x 每个 SM 含 4 个 Processing Block,组织方式如下:
| Block | FP32-only Lane | FP32-or-INT32 Lane | 合计 |
|---|---|---|---|
| 0 | 16 | 16 | 32 FP32 or 16 FP32 + 16 INT32 |
| 1 | 16 | 16 | 同上 |
| 2 | 16 | 16 | 同上 |
| 3 | 16 | 16 | 同上 |
| SM-level | — | — | 128 FP32 or 64 FP32 + 64 INT32 ops/cycle |
总资源:128 FP32 CUDA Core / 128 INT32 / 4 FP64(比例 1:64)/ 1 个第三代 Tensor Core / 4 warp scheduler / 4 dispatch unit。
FP32 吞吐的硬件含义:128 FP32 ops/cycle 的峰值在纯 FP32 workload 下四个 block 的 FP32-only 与 FP32-or-INT32 datapath 均可服务 FP32,因此可达。混合 FP32+INT32 workload 下,每个 block 可提供 16 FP32 + 16 INT32 ops/cycle,四个 block 合计 64 FP32 + 64 INT32 ops/SM/cycle。这里描述的是 SM aggregate execution throughput,不应写成"Block 2/3 成为瓶颈"的固定叙事。
这一组织在 NVIDIA 的 Ampere GA102 白皮书中有明确描述:每个 SM partition 的一条 datapath 含 16 个 FP32 CUDA Core,另一条含 16 个 FP32 + 16 个 INT32 Core,每 partition 每时钟可执行 32 FP32 或 16 FP32 + 16 INT32 操作,四个 partition 合计 128 FP32 ops/clock,恰为 Turing SM 的两倍。同一份白皮书还给出了 GDDR6X 的接口数字:PAM4 信令将单 pin 数据率推至 19.5 Gbps,RTX 3090 的 384-bit 接口峰值带宽 936 GB/s,落在 6.5 节给出的有效带宽区间之内。
第三代 Tensor Core:
第三代 Tensor Core 相比 Turing 的第二代,主要变化在于:
- 新增 TF32 与 BF16 运算模式
- 引入 Structured Sparsity(2:4 模式) 硬件支持
2:4 稀疏的硬件实现:权重矩阵以 4 个元素为一组,其中恰好 2 个为零。压缩后的权重以 50% 存储空间保存非零值,并附带 2-bit metadata(指示哪两个位置为非零)。Tensor Core 在执行 MMA 时读取 metadata,跳过零值乘法,在相同时钟/面积预算下将 effective throughput 翻倍。注意:2:4 稀疏是硬件约束的稀疏模式,非任意稀疏。开发者需通过 NVIDIA APEX 库或 cuSPARSELt 将 dense 权重剪枝并压缩为 2:4 格式。硬件不自动处理任意稀疏矩阵。
第二代 RT Core (GA10x):
GA10x 继承并扩展了 Turing 的 RT Core,主要改进在 BVH traversal 的 pipelining:第二代 RT Core 增加了对 interleaved traversal + intersection 的硬件支持,允许在一个 ray 等待 memory fetch 时切换处理另一个 ray,提升了 traversal unit 的利用率。同时,triangle intersection test 的 throughput 提升约 1×。GA100 的 RT Core 能力被弱化(仅 SM80 的基本光追支持),图形非其设计目标。
GA100 (A100) SM
GA100 SM 为数据中心场景重新平衡了资源:
| 资源 | GA100 / SM | GA10x / SM | 设计意图 |
|---|---|---|---|
| FP32 CUDA Core | 64 | 128 | 减半,腾出面积给 FP64/Tensor/SM 数量 |
| FP64 CUDA Core | 32 | 4 | 1:2 比例,服务 HPC |
| INT32 | 64 | 128 | 减半 |
| Tensor Core | 4× 3rd-gen | 1× 3rd-gen | 4 个 quarter-SM 各一个 |
| SM 总数 (A100) | 108 | — | aggregate throughput 最大化 |
GA100 将 SM 内部进一步划分为 4 个 processing cluster(有时称为 quarter-SM),每 cluster 含 16 FP32 + 8 FP64 + 16 INT32 + 1 Tensor Core。4 个 cluster 共享 L1 cache / shared memory / register file,但各自拥有独立的 warp scheduler 与 dispatch logic。这种 subdivided 组织让 GA100 在 chip-level 能容纳更多 SM(108 vs GA102 的 80),总 aggregate FP32 throughput 仍超过 GA10x,但以牺牲单-SM 图形能力为代价。
Ada SM 结构
Ada AD10x 的 SM 组织与 GA10x 几乎一致:4 Processing Block / 128 FP32 / 128 INT32(对称的 16 FP32-only + 16 FP32-or-INT32 lane per block)/ 256 KB RF / 128 KB L1/Shared Memory。Ada 的性能提升不来自 SM 内资源扩容,而来自三条外部路径:
- TSMC 4N 工艺带来的频率提升:AD102 boost 频率可达 2.5 GHz+,相比 GA102 的 ~1.9 GHz 提升约 30%,直接线性放大所有 SM-level throughput。
- L2 容量与带宽的飞跃:AD102 72 MB L2 为 GA102 6 MB 的 12 倍,降低了 effective memory latency,缓解了 occupancy 对 latency hiding 的依赖。
- Tensor Core / RT Core / SER / OFA 等专用单元的代际升级。
第四代 Tensor Core (Ada)
Ada 的第四代 Tensor Core 在消费级产品线中引入 FP8 支持(E4M3/E5M2),保留并优化了 2:4 structured sparsity 路径。相比 Ampere 第三代,第四代 Tensor Core 的 FP16/BF16/INT8 峰值 throughput 也有约 1.5–2× 提升,来源为内部乘法阵列的更高频率与更细粒度的数据 gating。TF32 路径同样获得 frequency scaling 收益。
Ada 的 FP8 与 Hopper 的 FP8 存在明确区分:
- Ada FP8:面向 inference,支持 E4M3/E5M2 存储格式与 MMA,无细粒度 per-tensor scaling,无 RND。适合部署已训练好的 Transformer 模型进行低精度推理。
- Hopper FP8:面向 training,Transformer Engine 提供硬件自动的格式选择(E4M3 forward / E5M2 backward)、动态 per-tensor scaling 与舍入模式管理。两者在 ISA/PTX 层面的暴露也不同。
第三代 RT Core (Ada)
第三代 RT Core 的主要升级:
- Triangle-Box intersection test 吞吐翻倍:BVH traversal 中包围盒与光线相交测试的 throughput 提升至第二代 2 倍。这是通过增加 traversal pipeline 的并行度与改善 memory fetch coalescing 实现。
- Opacity Micromap (OMM) Engine:硬件化的 alpha test 加速单元。在传统路径中,光线命中透明/半透明几何后需回退到 SM shader 进行 alpha evaluation,造成严重的 pipeline bubble。OMM 允许将预计算的 opacity 信息(micro-triangle 级别的透明度)编码在 BVH 节点中,RT Core 在 traversal 阶段直接解析并可能直接跳过透明区域,无需 SM 介入。
- Displaced Micro-Mesh (DMM) Engine:硬件化的 displacement mapping 支持。DMM 将高细节位移表面实时细分为 micro-mesh,直接在 RT Core 中生成精细几何用于 ray intersection,替代了传统 tessellation + SM shader 的复杂路径。OMM 与 DMM 的硬件代价为 RT Core 中新增的固定功能逻辑,不占用 SM 的 shader 资源。
Optical Flow Accelerator (OFA)
Ada 集成了 Optical Flow Accelerator,用于加速帧间光流估计。OFA 的硬件路径独立于 SM/RT Core/Tensor Core,接收相邻帧像素数据后输出 motion vector field,供 DLSS 3 Frame Generation 生成中间帧。OFA 的 throughput 为 306 TFLOPS (optical flow specific),帧生成因此不占用 SM/Tensor Core 资源,避免了对游戏渲染并行度的干扰。
6.4 Register File
Ampere Register File
Ampere 两代产品线(GA100 与 GA10x)的 SM 级 RF 组织一致:256 KB / SM,划分为 4 × 64 KB partition,每个 partition 服务于一个 Processing Block。
- 每 partition 提供 2 读 + 1 写端口(典型配置),4 partition 合计 8 读 + 4 写,支撑 4 block 并发 warp 的 operand read/write 需求。
- RF partition 与 operand collector 的 crossbar 连接允许多个 warp 同时访问各自 partition,避免 bank conflict。
- RF 与 L1 Data Cache / Shared Memory 的物理紧邻布局构成 SM 内核心 datapath:Operand Collector → RF read → ALU input / LSU address generation → Writeback → RF write / L1 store。
GA100 与 GA10x 的关键差异在 shared memory / L1 容量:
- GA10x 每个 SM 拥有 192 KB on-chip memory(GA102 等部分 SKU 为 128 KB),可配置为 L1 cache + Shared Memory 的不同比例(0/64/96/128 KB shared memory 等)。
- GA100 每个 SM 的 shared memory 为 164 KB(部分 early doc 记为 192 KB,实际可用受 quarter-SM 划分影响),同样可配置。GA100 的 L1 cache 与 shared memory 在 quarter-SM 级别共享,software-visible 配置空间与 GA10x 类似,但物理组织更细碎。
Ada Register File
Ada AD10x 完整继承 Ampere 的 256 KB / 4×64 KB RF 组织。AD102 / AD103 / AD104 均维持此容量不变。Ada 的 performance-per-SM 提升来源并非 RF 扩容,而是:
- 频率提升:同 register count 下,更高 clock rate 意味着每周期更多 warp 可完成 read/write,提升 effective RF bandwidth。
- L2 缓存扩至 72 MB:降低了从 RF spill 到全局内存的需求(更多数据可被 L2 capture),间接缓解 RF pressure。
- SER 的 locality 改善:更好的 cache locality 减少因 cache miss 导致的 warp stall,使 RF 中的活跃 warp 更有效地推进执行。
因此,Ada 这一代"更多寄存器容量意味着更高 occupancy"的说法不适用:Maxwell–Ampere 以来 SM RF 容量首次未增长,occupancy 提升依赖缓存与调度的外部优化。对于 heavy register-pressure kernel,开发者仍可能在 Ada 上观测到与 Ampere 类似的 register spill 行为。
6.5 Memory Subsystem
Ampere 内存架构
Ampere 的内存子系统体现了数据中心线与图形线的明确分野:
GA100 (A100):
- L2 Cache:40 MB,16-way set associative,分为与 HBM2 PHY 数量对应的多个 slice。L2 作为 SM 与 HBM2 之间的主要 buffer,其容量设计目标是在 AI training workload 中 capture 大部分权重/激活的复用,减少对 HBM2 的重复访问。
- HBM2:4096-bit 接口,带宽 1.5–2.0 TB/s(SKU 差异)。HBM2 的高 pin count 与 stacked 封装为代价(芯片面积、功耗、成本),换取高带宽、低延迟的内存访问。GA100 的 40 MB L2 配合 HBM2 的高带宽,大规模矩阵乘法中的 memory-bound 阶段因此得到有效覆盖。
- L2 Atomic:相比 Turing,GA100 优化了 L2 cache 的原子操作处理路径,将部分 atomic 操作(如
atomicAdd64-bit)的 throughput 提升约 1×,对并行规约类算法有益。
GA10x (GA102/GA104/GA106):
- L2 Cache:GA102 为 6 MB(RTX 3090/3080),GA104 为 4 MB,GA106 为 3 MB。相比 GA100 的 40 MB,图形线的 L2 容量小一个数量级,原因在于图形 workload 的 memory footprint 特征不同(texture streaming、framebuffer、随机显存访问),且 GDDR6X 的带宽足够高,降低了对巨大 L2 的依赖。
- GDDR6X:GA102 采用 384-bit GDDR6X 接口(19–21 Gbps/pin),通过 PAM4 (Pulse Amplitude Modulation 4-level) 信令在每个 clock 传输 2-bit 数据,相比 GDDR6 的 NRZ 信令带宽提升约 1×。PAM4 的代价是信噪比降低、信号完整性要求更高,导致内存控制器与 PHY 的功耗增加。GDDR6X 的有效带宽约 760–1000 GB/s,低于 HBM2 但成本低得多。
- RTX IO:基于 DirectStorage API,允许 GPU 直接从 NVMe SSD 解压缩数据至显存,绕过 CPU 与系统内存。硬件路径上依赖 GA10x 的 DMA engine 与 decompressor,减少传统 I/O 路径的 latency。
Ada 内存架构
Ada 内存子系统的主要变化是 L2 缓存容量的数量级增长:
AD102 (RTX 4090):72 MB L2 Cache(AD102 完整 die 配备 96 MB,RTX 4090 SKU 启用其中 72 MB),为 GA102 (6 MB) 的 12 倍。这一设计哲学实际上就是 "以缓存换带宽":在 GDDR6X 带宽增长有限(384-bit @ 21 Gbps ≈ 1000 GB/s)且功耗日益受限的背景下,通过将 L2 容量扩展至 72 MB 来提升 effective bandwidth、降低 average memory access latency。
Chips and Cheese 对 RTX 4090 的微基准实测为这一判断提供了第三方佐证。他们的延迟测试确认 AD102 die 内物理配备 96 MB L2、RTX 4090 启用其中 72 MB。带宽扩展测试在全 SM 负载下测得约 5 TB/s 的 L2 聚合带宽,接近 RTX 3090 (84 SM) 的两倍。他们对这一设计的解读与该节一致:Ada 的显存带宽相比 Ampere 提升有限,L2 的容量跃升正是为了对冲带宽缺口。容量扩大 12 倍的同时,L2 命中延迟反而比 Ampere 低了约 30 ns,容量与延迟在这里并非此消彼长。
72 MB L2 的硬件含义:
- 数据复用捕获:在 ray tracing 中,incoherent secondary ray 的 hit point 可能散布在大量不同 texture / geometry 数据中。大 L2 可捕获更多这种跨 ray 的数据复用,减少 GDDR6X 访问。
- SER 配合:SER 对 shader invocation 的重排依赖数据在 cache 中的驻留能力。72 MB L2 为 reordering buffer 的 output 提供了足够 cache footprint,使重排后的 locality 收益得以兑现。
- 功耗角度:L2 access 能耗约为 GDDR6X access 的 1/10–1/20。大 L2 通过减少外部显存访问次数,可在 total power budget 固定的情况下释放更多功耗给 SM/RT Core/Tensor Core。
- 代价是 72 MB L2 占用大量芯片面积(约 15–20% die area),这部分面积在 Ampere 中本可用于更多 SM 或其他 logic。
AD103 / AD104 的 L2 配置相应缩减(AD103: 64 MB, AD104: 48 MB),维持产品线梯级。
Ada 继续使用 GDDR6X 显存接口,AD102 为 384-bit @ 21 Gbps,AD104 缩减至 256-bit。内存控制器在 Ampere 基础上优化了 PAM4 信噪比处理与错误纠正能力,但未引入根本性变革。
GPU TLB 层级与地址翻译
GPU 的虚拟地址翻译同样依赖多级 TLB 结构,其层级与计算单元拓扑对齐:
- L1 TLB(SM 级):每个 SM 内置独立的 instruction TLB 与 data TLB,服务本 SM 的地址翻译请求。在 TPC 层面,2 个 SM 共享 L1 TLB 的物理存储,指令与数据通道分离。A100 上 L1 TLB 为 16-way set associative,I-TLB 与 D-TLB 各自独立,这些参数是跑 microbenchmark 拿到的。
- L2 TLB(GPC 级):同一 GPC 内的所有 TPC 共享一个 L2 TLB。microbenchmark 实测显示 A100 上 L2 TLB 为全 GPU 共享、8-way set associative。
- L3 TLB(全芯片级):跨 GPC 的最后一级翻译缓存,miss 后触发 page table walk 访问显存中的页表。
L2/L3 TLB 支持 sub-entry 机制:单个 TLB entry 覆盖 1 MB 虚拟地址范围,内部拆分为 16 个 sub-entry,分别映射 16 个 64 KB 物理页。这一设计在不增加 entry 总数的前提下扩大了有效覆盖范围。映射粒度支持 64 KB 与 2 MB 两种页大小。
TLB miss 的性能代价在 GPU 上被 warp 执行模型放大:warp 内 32 线程锁步执行,任何一个线程触发 TLB miss 即拖累整个 warp stall。当内存访问范围超过约 2 GB 时,TLB 工作集溢出导致 latency 陡增,这个拐点跑 benchmark 很容易观察到。大量并发 page walk 还会挤占 L2/L3 TLB 容量,形成 miss 级联。推测早期架构(Tesla/Fermi)SM 级 TLB 已存在,但容量有限、workload 的地址空间尚未大到暴露瓶颈。随着模型规模膨胀至数十 GB,TLB 压力才成为可观测的性能因素。
6.6 Function Feature
Graphics 路径
Ampere GA10x 的图形管线在 Turing 基础上增强:第二代 RT Core 提供更高的 BVH traversal throughput,SM 的 doubled FP32 能力加速传统 rasterization 中的 pixel/vertex shader。但 Ampere 图形线的主要瓶颈在于 incoherent ray workload 中 cache footprint 的急剧膨胀:secondary ray 的 divergence 导致 texture cache thrashing,SM occupancy 因长延迟内存访问而下降。
Ada 针对这一瓶颈的改进落在三条硬件路径:
- 第三代 RT Core:triangle-box test 吞吐翻倍直接加速 BVH traversal,OMM 将 alpha test 从 SM shader 卸载至 RT Core 以减少 traversal 中的 shader bubble,DMM 将 displacement geometry 的生成从 tessellation pipeline 转移至 RT Core 硬件,降低 SM 负载。
- SER:在 SM frontend 对 incoherent shader invocation 进行重排,改善 L1/L2 cache locality。SER 的收益与 scene 复杂度、ray coherence 程度正相关。在 fully coherent primary ray 场景中,SER 的 reordering overhead 可能导致轻微负收益。
- 大 L2:72 MB L2 为上述两个机制提供数据驻留基础。OMM/DMM 产生的 micro-geometry 数据、SER 重排后的 texture access pattern,均依赖 L2 的 capture 能力才能避免被 GDDR6X 带宽 bottleneck。
Compute 路径
Ampere GA100 的 compute 路径以第三代 Tensor Core 为核心:TF32/BF16/FP16/INT8 的多精度覆盖、2:4 structured sparsity 的 throughput 翻倍、async copy 对 register pressure 的缓解,使其在 AI training 中相比 Turing 有 2–5× throughput 提升(workload-dependent)。40 MB L2 + HBM2 2 TB/s 的内存配置确保了大模型训练中的 memory bandwidth 不构成硬性瓶颈。
Ada 的 compute 路径在消费级产品线上扩展了 FP8 inference 能力:第四代 Tensor Core 的 E4M3/E5M2 MMA 路径在 Transformer-based model(如 Stable Diffusion、LLM inference)中提供比 Ampere FP16/INT8 更高的 ops/Watt。但 Ada 的 FP8 缺乏 Hopper 的细粒度 scaling 与训练支持,定位明确为 inference-only。
Ada 的 72 MB L2 对 compute workload 的收益取决于数据复用度:对于 LLM inference 中的 KV-cache 访问,大 L2 可有效降低 memory bandwidth pressure。对于纯 compute-bound GEMM,L2 容量超出 working set 后收益递减。
6.7 小结
Ampere 到 Ada 的演进,展示了 NVIDIA 在两条产品线上差异化的体系结构策略:
Ampere — 分支化
GA100 与 GA10x 在 SM 结构、内存子系统、功能单元上发生明确分化,NVIDIA 在同一代架构内部首次对数据中心与图形市场进行深度 hardware specialization。GA100 以 FP64、HBM2、MIG、40 MB L2 服务 HPC/AI training,GA10x 以 doubled FP32、RT Core、GDDR6X 服务游戏/图形/工作站。两者共享 ITS 调度模型、128-bit SASS、第三代 Tensor Core 等基础框架,但 resource allocation 的侧重完全不同。
Ada — 图形线的纵深
Ada 未延续 GA100 的数据中心路线(该路线由 Hopper 接管),而是在 GA10x 的图形路径上纵深推进。主要特征并非 SM 内资源扩张(RF 容量、scheduler 数量均未变),而是三条外部优化路径的叠加:
- 工艺频率:TSMC 4N 的 clock scaling 直接线性放大 SM throughput。
- 缓存纵深:72 MB L2 降低了 memory hierarchy 的 effective latency,为 SER 与 RT Core 的新 workload pattern 提供数据驻留基础。
- 专用单元密度:第四代 Tensor Core (FP8)、第三代 RT Core (OMM/DMM)、OFA、SER,每个单元解决特定 bottleneck,而非扩展通用计算能力。
这种设计反映了图形/消费级 GPU 在后摩尔定律时代的一条务实路径:不追求通用 peak FLOPS 的增长,而是通过专用化、缓存化、调度智能化来提升目标 workload 的有效 performance。
两代架构的关键约束:
- RF 容量未增长(256 KB/SM 自 Ampere 至 Ada 不变),occupancy 提升依赖外部缓存/调度优化,register-pressure-heavy kernel 的 spill 行为未改善。
- SER 的 reordering 引入额外状态保存开销,高 register pressure shader 可能无法从 SER 获益。
- "以缓存换带宽"的大 L2 策略在 chip area 与 yield 上存在代价,72 MB L2 约占据 AD102 15–20% die area。
- FP8 在 Ada 与 Hopper 上的不同定位(inference vs training)要求开发者明确精度与数值稳定性的 workload 需求。
七、Hopper (2022)
NVIDIA Hopper 架构于 2022 年发布,面向数据中心计算(H100 SXM5/PCIe)。全系列聚焦其数据中心产品线的微架构行为,不涉及消费级 Ada 的 feature 对比。NVLink/NVSwitch/Grace-Hopper 等平台级系统属多 GPU 互联与 scale-out 范畴(见前言)。
Hopper 面对的问题是:在 Ampere 已奠定混合精度计算与大容量片上缓存的基础上,如何进一步将理论算力转化为有效吞吐。其解法围绕三条主线展开:(1) 精度下沉至 FP8,配合 Transformer Engine 的软硬件协同缩放机制。(2) 数据移动从线程驱动转向 descriptor-driven 的 TMA 异步引擎。(3) CTA 边界从 SM 内扩展到 GPC 内的跨 SM 协作(Thread Block Cluster + DSMEM)。执行模型本身未变:SIMT、独立线程调度、定长 128-bit 指令,保证 CUDA 生态兼容。
7.1 ISA
Hopper ISA 的增量设计围绕两个约束:一是必须与 Ampere (SM 8.x) SASS 保持向后兼容,确保既有 CUDA 程序可不经重编译直接运行。二是必须为 FP8 运算、TMA 异步数据移动、DPX 复合操作、以及 warpgroup 级动态寄存器重分配提供编码空间。
保持与继承
Hopper 延续 Volta/Turing 的 Independent Thread Scheduling 模型与 128-bit 定长指令格式,SASS 与 Ampere 保持编码层面的连续性。硬件 Scoreboard 逐线程跟踪寄存器读写依赖,维护并发一致性。PTX 作为虚拟 ISA 仍承担中间抽象层角色,但全系列讨论的是映射到硬件的 SASS 层面行为。
TF32、BF16、FP16、FP64、INT8 等前代数据格式及对应指令均完整保留,映射关系不变。
新数据类型与算术指令
FP8(数据中心线首次支持)
Hopper 为配合第四代 Tensor Core 引入两种 FP8 格式:E4M3(4 位指数,3 位尾数)与 E5M2(5 位指数,2 位尾数)。E4M3 偏向推理场景的动态范围需求,E5M2 偏向训练场景的梯度表示。Tensor Core 支持 FP8 矩阵乘积累加至 FP16 或 FP32,维持精度。操作数位宽从 FP16 的 16 bit 减半至 8 bit,同一 Tensor Core 在相同时钟周期内可处理的元素数量翻倍,理论矩阵运算吞吐相应提升。
ISA 层面,Hopper 新增了 FP8 矩阵乘加指令,与 Tensor Core 硬件协同。开发者通过 CUDA API 调用,编译器生成对应 SASS 指令驱动 Tensor Core 执行 FP8 GEMM。
DPX 指令集
Dynamic Programming eXecution (DPX) 指令集针对动态规划算法的内层循环模式。DP 算法的典型瓶颈在于"比较-选取-加法"操作链:每条依赖前一条的结果,形成串行数据依赖,传统 ISA 需多条独立指令完成。Hopper 将这一操作链融合为单条 DPX 指令(如 VIMNMX 系列),在单个时钟周期内完成比较、选择和累加。
硬件层面,SM 内集成了 DPX 复合运算单元,接收两个源操作数,执行 min/max + add 的 fused 操作,结果写回寄存器文件。这减少了指令发射次数和寄存器读写流量,降低了该操作链的 register pressure 和 dependency chain 长度。
当 kernel 的内层循环由 min/max-then-add 链条主导时(Smith-Waterman、Viterbi 等 DP 算法的典型模式),每步结果依赖前一步,传统 ISA 需要三条独立指令串行执行。DPX 复合运算单元将这三步融合为单条指令的单周期路径,warp 的指令发射数和 scoreboard 依赖条目占用时间同步下降。代价是 DPX 单元为专用结构,非 DP 负载无法利用。
异步数据移动与同步指令
TMA(Tensor Memory Accelerator)
Ampere 的 cp.async 已实现 Global→Shared 的异步拷贝,但地址生成和批量搬运仍需线程逐条参与:每个线程计算自己的加载地址,执行 scalar load,数据经 LSU 写入 Shared Memory。高维张量场景下地址计算占用 ALU 周期,线程级细粒度操作无法打满内存总线带宽。
Hopper 引入 descriptor-driven 的 TMA 引擎:单条指令(cp.async.bulk.tensor 系列)提交维度、步长、数据类型、源/目标地址等描述信息,硬件自动完成 1D–5D 张量的地址计算与批量搬运,线程发起后即可继续执行计算。硬件数据通路与瓶颈在 7.5 节 TMA 数据移动路径中展开。
Transaction Barrier
TMA 的异步执行需要配套的完成通知机制。Ampere 的 mbarrier(memory barrier)支持 cp.async 的到达-等待语义,但粒度为单条操作的完成计数。Hopper 将其升级为 transaction barrier:一个 barrier 对象可关联多个 TMA 操作的字节计数,当所有关联操作的字节传输完成时,等待线程被唤醒。
语义上分为 Arrive 与 Wait 两阶段:数据产生方(发起 TMA 的线程)以非阻塞方式通知 Arrive,数据消费方通过 Wait 挂起,直至 barrier 关联的所有传输字节计数归零。与 mbarrier 的区别在于:transaction barrier 跟踪的是字节完成量而非到达线程数,更适合批量异步传输的同步场景。
动态资源管理
SET.MAXNREG
传统 CUDA 中 CTA 启动时所有 warp 获得固定寄存器配额,运行期间不可更改。当 CTA 内不同 warpgroup 的 register pressure 差异很大(如 producer warpgroup 需大量寄存器缓冲中间结果、consumer warpgroup 仅需少量寄存器消费数据)时,固定配额导致资源闲置或溢出。
Hopper 通过 PTX 指令 setmaxnreg.inc / setmaxnreg.dec 允许 warpgroup 在运行时动态调整寄存器配额:某一 warpgroup 完成高寄存器需求阶段后释放部分寄存器至 CTA 级资源池,其他 warpgroup 再从池中申请。重分配不增加 SM 总额,仅在 CTA 内部流转。机制与硬件实现路径在 7.4 节动态寄存器重分配中展开。
7.2 Scheduling
Hopper 的调度体系是多层级结构,主要约束在于如何将 Thread Block Cluster 的跨 SM 协作与 SM 内部的 warp 级调度对接。
调度层次
调度体系分为三个层级:
- Grid 级:GigaThread Engine 将 grid 拆分为 CTA,分发到可用 GPC。这是粗粒度任务划分,与 Ampere 一致。
- Cluster 级:Thread Block Cluster 在 GPC 内部协调多个 SM 上的 block 并发执行,允许这些 block 作为整体进行同步和数据共享(通过 DSMEM)。Cluster 内所有 CTA 必须驻留在同一 GPC 内,这是 DSMEM 低延迟通信的硬件前提。若 Cluster 跨 GPC 配置,调度器会拒绝该配置。
- SM 内部:每个 SM 包含 4 个 Warp Scheduler,每周期从就绪 warp 中选择指令发射。H100 每 SM 支持最多 64 个 active warp(2048 线程),与 Ampere 持平。
SM 内部的 Warp 调度
Hopper 每个 SM 配置 4 个 Warp Scheduler,每个调度器在每个时钟周期可从就绪 warp 中发射一条指令。由于每 SM 集成 128 个 FP32 CUDA Core(较 A100 的 64 个翻倍),单个 warp 的 32 线程可在单周期内完成 FP32 指令发射。FP64 指令每 2 个周期完成发射(A100 需 4 周期)。
Scoreboard 继续承担 warp 内逐线程的依赖跟踪职责:每条指令发射前检查 Read-after-Write 依赖,满足条件后方可发射。硬件不实现 warp 级乱序执行,发射顺序仍按程序顺序,但 ITS 允许 warp 内部分线程因 predicate 不同而走不同执行路径。
高线程级并发(64 active warp / SM)的设计目标是通过快速切换就绪 warp 来隐藏内存访问延迟。当某一 warp 因等待 L1 cache miss 或 barrier 而 stall 时,scheduler 切换到其他 eligible warp 执行。
跨 SM 集群调度:Thread Block Cluster
Thread Block Cluster 是 Hopper 引入的新并行执行模型。一个 Cluster 包含 2-16 个 CTA(具体数目由启动参数决定),分布在同一 GPC 内的不同 SM 上,通过 DSMEM 共享数据。Cluster 内所有 CTA 必须驻留同一 GPC,这是 DSMEM 低延迟通信的硬件前提。Cluster 级同步通过 cluster.sync() 原语实现,映射到硬件级 cluster barrier:所有 Cluster 内 CTA 到达 barrier 后,方可继续执行。
数据通路(GPC 内 SM-to-SM 高速网络)与瓶颈在 7.5 节 DSMEM 硬件路径中展开。
GPU 级任务管理:MIG 2.0
Hopper 延续 Ampere 的 Multi-Instance GPU (MIG) 技术并升级至第二代。H100 可将物理 GPU 划分为最多 7 个独立逻辑实例,每实例拥有独立分配的 SM、L2 cache slice 和 HBM 带宽。MIG 2.0 增加了 Confidential Computing 支持:每个 MIG 实例可在 Trusted Execution Environment (TEE) 中运行,通过内存加密和访问控制在物理层面隔离不同实例的数据。DMA 引擎集成硬件加解密功能,保护 GPU-CPU 间的数据传输。
MIG 2.0 的目标场景是多租户 AI 推理:在同一物理 GPU 上并行运行来自不同用户的 workload,保证 QoS 和数据隔离。相关硬件机制(TEE、内存加密)引入一定的性能开销和面积代价,但对于数据中心和云计算市场,这是商业化部署的必要条件。
7.3 Execution Unit
Hopper SM 的执行单元配置在 Ampere 基础上进行了针对性扩展。思路是:在功耗和面积预算内,最大化 AI 和 HPC workload 的计算密度。由于 Hopper 面向数据中心,SM 中的图形固定功能单元(如 ROP、TEX、PolyMorph Engine 相关路径)被削减,晶体管资源向通用计算单元和 Tensor Core 倾斜。
CUDA Core 与标量 ALU
每 SM 资源配置如下:
| 单元类型 | H100 | A100 | 变化 |
|---|---|---|---|
| FP32 CUDA Core | 128 | 64 | 2x |
| FP64 CUDA Core | 64 | 32 | 2x |
| INT32 ALU | 64 | 64 | 持平 |
| 第四代 Tensor Core | 4 | 4 | 架构升级 |
FP32 单元翻倍使得每 SM 的 FP32 峰值吞吐在相同频率下较 A100 提升 2 倍。一个 warp 的 32 线程可在单周期内完成 FP32 指令发射(利用 32 个 CUDA Core)。Hopper 的 128 FP32 operations/SM/cycle 应理解为 SM aggregate execution throughput。它来自 SM 内更多 FP32 execution lanes 及四个 scheduler/sub-partition 的并行供给,而不是单个 warp 在同一周期发射两条 FP32 指令。对单 warp latency/issue 行为的分析仍需以 SASS dependency、scoreboard、operand collector 与 scheduler issue slot 为准。
FP64 单元也翻倍至 64 个,双精度 warp 指令的发射从 A100 的 4 周期降至 2 周期。这一增强直接服务于 HPC 场景的科学计算精度需求。
关于 FP32/INT32 数据路径的具体复用实现,公开资料未完全披露,不宜写成确定的"共享执行管线"结论。
第四代 Tensor Core
每个 SM 集成 4 个第四代 Tensor Core。相较于第三代(Ampere)的主要改进:
- FP8 支持:新增 E4M3 和 E5M2 格式的矩阵乘加能力。在标准稠密运算下,FP8 的理论吞吐达到 A100 FP16 的 4 倍。
- WGMMA 指令:Warpgroup Matrix Multiply-Accumulate。传统矩阵乘指令(如 Ampere 的
mma.sync)以单个 warp 为操作单位,而 WGMMA 以 warpgroup(4 个 warp,128 线程)为粒度调度 Tensor Core。WGMMA 指令由 warpgroup 协作提交,Tensor Core 以更大粒度进行矩阵分块运算,提高了指令发射效率和数据复用率。 - 2:4 Structured Sparsity:硬件支持 2:4 结构化稀疏模式。
- 累加精度可选:FP8 矩阵乘积可累加至 FP16 或 FP32,由指令编码指定。
Tensor Core 的数据路径在第四代进行了优化:内部矩阵分块尺寸调整,数据从 Shared Memory 经专用路径进入 Tensor Core 的 operand buffer,减少了通过通用寄存器文件中转的需求。
第四代 Tensor Core 的改进针对 AI workload 中矩阵运算的指令发射效率和数据供给带宽。硬件上,Tensor Core 内部数据路径经过优化,WGMMA 引入了 warpgroup-level 调度逻辑。数据从 Shared Memory 进入 Tensor Core operand buffer,经乘法阵列到累加器,再写回 Shared Memory 或 RF。调度层面,WGMMA 以 warpgroup 为粒度运作,4 个 warp 需同步参与,Tensor Core 操作期间 warp 处于占用状态但不一定占用 issue slot。新的瓶颈在于 Tensor Core 操作与 CUDA Core 操作的并发度受 Shared Memory 端口和 warp scheduler 资源限制。开发者可观察到 WGMMA 相比 mma.sync 在同等 GEMM 尺寸下指令数减少,FP8 GEMM 的算术密集度远高于 FP16。
DPX 复合运算单元
DPX 指令由 SM 内专用的复合运算单元执行。该单元在单周期内完成 min/max + add 操作,内部包含比较器、选择器和加法器的 fused 数据路径。输入为两个源操作数(均来自寄存器文件或操作数收集器),输出为结果寄存器。
DPX 单元与常规 CUDA Core 共享发射端口或拥有独立端口(公开资料未明确),但为专用结构,仅响应 DPX 指令编码。
图形固定功能的弱化
H100 的 SM 绝大部分晶体管资源被分配至通用计算单元(CUDA Core、Tensor Core、DPX 单元)和存储子系统(L1/Shared Memory、Register File)。与图形渲染相关的固定功能单元(ROP、TEX cache 的完整路径、PolyMorph Engine 等)被弱化或省略。Hopper 的定位是纯粹的数据中心计算 GPU,不支持图形输出,因此这些单元的移除不影响其目标 workload,反而释放了面积和功耗预算。
7.4 Register File
架构与容量
Hopper 每 SM 的 Register File (RF) 容量保持 256 KB(65,536 个 32-bit 寄存器),与 Volta、Ampere 一致。物理结构上,RF 被划分为 4 个 bank,分布于 SM 的多个子分区内,就近供给对应的 Warp Scheduler。这种分块设计降低寄存器访问的端口压力,支持多 warp 并行访问。
每 SM 64 active warp、每 warp 32 线程,共 2048 线程。在最大 occupancy 下,每线程平均可用 32 个寄存器(65,536 / 2048 = 32)。若 kernel 的 register demand 超过此值,active warp 数量减少,occupancy 下降。RF 容量未增加是 Hopper 的一个重要约束:SM 的计算吞吐翻倍(FP32 从 64 增至 128),但 RF 容量未同比例增长,在满 occupancy 场景下每线程可用的寄存器资源实际上被稀释。
Scoreboard 继续承担依赖跟踪职责。每条 warp 指令发射前检查 Read-after-Write (RAW) 依赖,满足条件后方可发射。Hopper 延续了这一方案,通过硬件维护的掩码和依赖计分板进行逐线程的精确依赖管理。
动态寄存器重分配:SET.MAXNREG 深度分析
SET.MAXNREG 是 Hopper 在 RF 层面的关键变更,下面拆解其机制与约束。
问题背景
传统 CUDA 中,CTA 的所有 warp 在启动时获得均等的寄存器配额(由编译器根据最坏路径的 register pressure 静态决定)。若 CTA 内存在 producer-consumer 模式:producer warpgroup 在执行阶段 A 需要大量寄存器(如展开多层循环、缓冲中间张量),consumer warpgroup 在阶段 B 仅需少量寄存器(如逐元素归约),固定配额导致阶段 A 的 producer 因寄存器不足而溢出到 Local Memory,阶段 B 的 consumer 则闲置大量未使用的寄存器。
机制
setmaxnreg 允许 warpgroup 在 Kernel 执行过程中阶段性调整寄存器配额:
- 释放阶段:producer warpgroup 完成高 register pressure 计算后,执行
setmaxnreg.dec N,将 N 个寄存器归还至 CTA 级资源池 - 申请阶段:consumer warpgroup 执行
setmaxnreg.inc M,从资源池中申请 M 个寄存器 - 约束:CTA 的总寄存器占用量始终不超过 SM 分配给该 CTA 的上限。动态调配仅在 CTA 内部流转,不增加 SM 总额
编译器协同
编译器在 PTX 层面插入 setmaxnreg 指令,将 Kernel 划分为 register demand 不同的区段。例如:
// 阶段 1: 高 register pressure 的张量生成
setmaxnreg.inc 128;
// ... producer 计算 ...
setmaxnreg.dec 64;
// 阶段 2: 低 register pressure 的消费与归约
// ... consumer 计算 ...
硬件实现路径
setmaxnreg 的操作落到 warp scheduler 和 RF 分配表上。每个 warpgroup 的寄存器配额记录在 scheduler 的硬件映射表中,setmaxnreg 指令修改该映射表的段边界,重新划分该 warpgroup 可访问的 RF 地址范围。RF 物理容量不变,仅逻辑分段调整。
SET.MAXNREG 解决的是 CTA 内 warpgroup 间 register pressure 不均衡导致的资源利用率低下和溢出问题。硬件上,warp scheduler 的寄存器映射表支持运行时重配,配合 CTA 级资源池管理逻辑,warpgroup 的 RF 地址分段边界可动态调整,同一物理 RF 在不同阶段服务不同 warpgroup 的容量需求。RF 与调度层面的影响是:warpgroup 的 register footprint 动态变化,直接影响 occupancy 计算和 warp 驻留数。setmaxnreg 操作本身引入调度点,可能导致短暂 stall。限制在于:setmaxnreg 为 warpgroup-level hint,sm90a 架构下存在限制和阻塞。频繁调整引入指令开销和调度波动。编译器需精确划分阶段,阶段边界错位可能导致资源浪费。开发者可观察到 producer-consumer pipeline 的 Local Memory spill 减少,occupancy 曲线出现阶段性变化。setmaxnreg 使用不当(如频繁增减或阶段划分不准)则可能出现性能下降。
与 SM 总额的关系
要点:SET.MAXNREG 不改变 SM 分配给 CTA 的寄存器总额。若 SM 为某 CTA 分配了 256 个寄存器/线程的配额,该 CTA 内所有 warpgroup 的寄存器总和仍受此上限约束。动态重分配只是将这 256 个寄存器在 CTA 内部的不同 warpgroup 和不同阶段之间重新划分。
7.5 Memory Subsystem
Hopper 内存子系统的升级围绕两条主线:片上缓存容量扩大以提升数据局部性,显存带宽提升以降低外部数据供给瓶颈。同时,TMA 和 DSMEM 新增了异步数据移动和跨 SM 共享的两条新数据通路。
L1 Cache / Shared Memory
H100 SM 有 256 KB combined L1/shared pool,较 A100 的 192 KB 增幅 33%。其中 shared memory carveout 最高 228 KB,不要把 256 KB 直接写成可用 shared memory。这 256 KB 可按需划分为 L1 Cache 和 Shared Memory 的比例(通过编译器选项或 CUDA API 配置)。这组参数与 NVIDIA 官方的 Hopper 架构解析一致:官方资料确认 H100 的 L1/shared memory 合并池为 256 KB、为 A100 的 1.33 倍,shared memory carveout 上限 228 KB。
更大的 Shared Memory 允许分块算法(如矩阵乘法的 tiling、FFT 的 stage buffer)采用更大的 tile size,减少分块次数,降低外层循环的迭代开销和寄存器压力。更大的 L1 Cache 则提升了非规则访存模式(如稀疏矩阵的索引访问、attention 机制中的 key-value lookup)的缓存命中率。
硬件层面,L1/Shared Memory 继续采用 banked 结构,多端口并行访问。TMA 引擎直接写入 Shared Memory,与线程通过 LSU 的写入共享存储端口,存在结构性竞争。
L2 Cache
H100 SXM5 配置约 50 MB L2 Cache,较 A100 的 40 MB 增加 25%。L2 采用双分区架构,两个物理分区通过内部互连桥接为统一地址空间。每个分区独立服务不同的 GPC 簇,通过 crossbar 实现统一寻址。这一双分区结构的可观察行为有公开实测佐证:Chips and Cheese 在 H100 上的微基准显示,任意线程都能访问全部 50 MB L2,但访问远端分区的延迟接近本地分区的两倍,已与 RX 6900 XT 的显存访问延迟相当。Hopper 的 L2 因此更适合被理解为带宽池而非低延迟的最后一级缓存,这与上文的结构分析互为印证。
50 MB 的 L2 容量可容纳更大规模的模型权重或 HPC 工作集。例如,在 LLM 推理的 KV-cache 场景中,更大的 L2 意味着更多层/头的 key-value 对可驻留片上,减少 HBM 访问。Hopper 继续支持 L2 cache 的逐出策略配置和压缩技术。
HBM 显存
H100 SXM5 配备 80 GB HBM3 显存,总带宽 3.35 TB/s。较 A100 80GB HBM2e 的约 2 TB/s 提升约 50%。HBM3 通过提高 I/O 速率(pin speed)和通道数实现带宽增长,物理层采用更激进的信号传输方案。
PCIe 接口升级至 Gen5,总带宽 128 GB/s(Gen4 的 2 倍)。这是主机-GPU 数据传输的瓶颈路径,对需要从 CPU 侧加载大量数据的 workload(如大数据预处理、图计算)有直接影响。
TMA 数据移动路径
TMA 引擎的数据路径独立于线程的 LSU:
Global Memory (HBM) → Memory Controller → TMA Engine → Shared Memory
↑
Thread ( LSU )
TMA 引擎接收线程提交的 descriptor(包含源地址、目标地址、维度信息、步长等),自主完成地址计算和批量数据搬运。descriptor 本身存储在 Global Memory 或 Shared Memory 中,TMA 引擎读取 descriptor 后解析并执行传输。
TMA 支持在写回 Global Memory 时执行元素级的聚合操作(如 atomic add)。TMA 操作与线程计算完全异步,通过 transaction barrier 同步完成状态。
当大规模矩阵 tiling 需要从 HBM 搬运高维张量切片时,cp.async 要求每个线程各自计算加载地址并执行 scalar load,地址生成本身就消耗大量 ALU 周期,线程级细粒度操作也无法打满内存总线带宽。TMA 引擎接收 descriptor 后自主完成 1D–5D 张量的地址计算与批量搬运,数据通路绕过线程 LSU 直接从 HBM 经 memory controller 进入 Shared Memory。瓶颈在于 TMA 引擎数量有限(每 SM 1 个),多个 warp 同时提交请求时会串行化,descriptor 的 cache locality 也影响地址解析延迟。实测行为表明 TMA 批量搬运的有效带宽远高于线程级 cp.async,但 descriptor miss 会导致 TMA 启动延迟显著增加。
DSMEM 硬件路径
DSMEM(Distributed Shared Memory)在 Thread Block Cluster 启用时激活。其硬件路径如下:
SM-A (发起访问的线程)
→ LSU 发出 DSMEM 请求
→ GPC 内 SM-to-SM 网络 (crossbar/ring)
→ SM-B 的 Shared Memory 端口
→ 数据返回 SM-A 的寄存器文件
DSMEM 请求由线程的 LSU 发出,经 GPC 内专用网络路由到目标 SM 的 Shared Memory。访问延迟远低于 Global Memory 路径(推测约为 Shared Memory 本地访问的 2-5 倍,而非 Global Memory 的数十倍),但仍高于本地 Shared Memory 访问。
DSMEM 支持 load、store 和 atomic 操作。地址空间在 Cluster 内统一:每个线程可通过 cluster.map_shmem() 获取其他 block 的 Shared Memory 基地址,加上偏移量直接访问。
当 Cluster 内多个 CTA 需要交换中间结果(如 producer-consumer 模式或并行归约)时,传统路径必须经 Global Memory 中转,延迟和带宽开销都很高。DSMEM 在 GPC 内新增了 SM-to-SM 高速网络,SM LSU 新增 DSMEM 地址译码和路由逻辑,数据从 SM-A 经 GPC 网络直达 SM-B 的 Shared Memory,绕过 L2 和 HBM。DSMEM 访问与本地 Shared Memory 访问共享 SM 的存储端口,Cluster barrier 负责同步 Cluster 内所有 CTA。瓶颈在于 GPC 内网络带宽有限,多个 CTA 同时高频率访问远程 Shared Memory 时产生争用,且 Cluster 规模受 GPC SM 数量限制(通常最多 8-16 SM/GPC)。实测行为表明 DSMEM 访问延迟介于本地 Shared Memory 和 L2 之间,Cluster 内跨 block 通信无需再经 Global Memory。
Page Fault 处理与地址翻译加速
TMA 和 DSMEM 解决的是"数据搬运路径"问题,但在 Unified Virtual Memory 场景下,数据搬运的前置步骤(地址翻译)本身也是延迟瓶颈。GPU 的 TLB miss 处理成本远高于 CPU。
早期 IOMMU 方案(以 AMD IOMMUv2 为代表)的路径:GPU TLB miss → 发起 ATS(Address Translation Service)请求 → 经 PCIe 到达北桥 IOMMU → 最多四级页表遍历。实测 TLB miss 延迟约为 CPU 的 25 倍。延迟来源可分解为:PCIe 往返传输、多级页表串行查找、IOMMU 无法窥探 CPU cache 中已驻留的 PTE(必须访问内存)、以及 miss warp 的暂停与重调度开销。
Page fault 的处理链路更长:GPU 侧 IOMMU 发起 PPR(Peripheral Page Request)→ 写入 memory-mapped 事件队列 → CPU 中断 → IOMMU driver 的 work-queue 派发 → worker thread 执行页面分配/迁移 → 通知 IOMMU 完成 → GPU retry 该访问。实测表明,真正的 page fault 处理(页面分配、映射建立)耗时占比不大,OS 调度延迟(中断响应、worker thread 唤醒)才是主要瓶颈。
NVIDIA 在后续架构中将 page table walk 能力下放到 GPU 侧。GMMU(GPU Memory Management Unit)内置 Page Walk Queue、Page Walk Cache 和独立的 Page Table Walker 硬件,支持 8 个并发 page table walk(microbenchmark 实测得出的并发数)。GPU 本地完成翻译失败时才向 CPU 侧的 Host MMU(支持 16 路并发)发起请求。这一分层设计将大量 TLB miss 拦截在 GPU 本地,避免 PCIe 往返。同时,硬件加速的 page fault 处理路径(GPU 侧直接触发页面迁移)比纯软件中断驱动方案快约 4.5 倍,实测行为表明改善相当可观。
Grace Hopper 进一步消解了这一问题。NVLink-C2C 提供 cacheline 粒度的 CPU-GPU 一致性访问,CPU 与 GPU 共享同一物理地址空间。远程数据访问在硬件层面以 cache miss 形式处理,不再触发系统性的 page fault 和页面迁移。地址翻译的瓶颈从"跨总线多级查表"收敛为片上 cache 一致性协议的固有延迟,量级从微秒降至百纳秒。
GPU 间互连(简要)
H100 配置第四代 NVLink,每 GPU 最多 18 条链路,双向总带宽 900 GB/s。配套的 NVSwitch 3.0 支持 multicast 和 in-network reduction。这些属于多 GPU 互联与 scale-out 范畴(见前言范围说明)。
7.6 Function Feature
Transformer Engine
Transformer Engine (TE) 是 Hopper 针对 Transformer 模型(尤其是 LLM)的软硬件协同机制。问题在于:FP8 的低精度表示区间有限,直接使用 FP8 进行训练会导致梯度下溢(underflow)或精度损失,影响模型收敛。
TE 的解决路径是 dynamic scaling / per-tensor scaling:
- 统计阶段:每次前向/反向传播中,TE 统计激活值和权重的绝对最大值(amax)
- 缩放计算:根据 amax 计算缩放因子(scale factor),将数值范围映射到 FP8(E4M3 或 E5M2)的有效表示区间
- 精度选择:Tensor Core 执行 FP8 GEMM,累加至 FP16/FP32,在数值敏感的操作(如 softmax、layer norm)回退到 FP16/FP32
- 迭代调整:缩放因子在迭代间动态更新,适应不同层的数值分布变化
TE 不是"魔法般地自动选精度"。它的机制是:硬件(Tensor Core 的 FP8 支持)提供低精度运算能力,软件(TE 库)根据每层激活分布动态决定是否使用 FP8、使用哪种 FP8 格式(E4M3 vs E5M2)、以及缩放因子大小。精度选择有明确的 heuristics:前向激活通常用 E4M3(范围需求小),反向梯度通常用 E5M2(范围需求大)。
当训练 kernel 在 FP8 精度下出现梯度下溢或精度损失时,根源在于 FP8 的窄表示区间无法覆盖不同层的数值分布。TE 的缩放逻辑主要在软件(CUDA 库)中实现,但依赖硬件提供 amax 统计指令。数据路径为:激活值 → amax 统计 → scale factor 计算 → FP8 转换 → Tensor Core GEMM → FP32/FP16 累加。调度层面,TE 在 kernel 边界插入额外的 scaling kernel,增加 kernel launch 数量和同步点。per-tensor scaling 的粒度在 activation 分布不均匀的 layer 上可能不足。实测行为表明 TE 开启时训练吞吐有明显提升(FP8 GEMM 的 2x 吞吐优势),但某些模型结构对 FP8 敏感,可能出现精度下降,需逐模型验证。
2:4 Structured Sparsity
Hopper 的第四代 Tensor Core 支持 2:4 结构化稀疏模式:在一个 4 元素向量中,最多 2 个非零元素。硬件利用这一结构知识,在矩阵乘法中跳过零元素,实现 2 倍理论吞吐提升。
关键约束:
- 权重矩阵必须经过训练后的稀疏化处理,满足 2:4 结构化稀疏格式
- 需同时提供元数据(metadata)指明非零元素位置
- Tensor Core 根据元数据索引非零元素,执行压缩后的矩阵乘法
硬件并非自动检测并跳过零元素,而是软件训练流程(pruning 至 2:4 模式并编码元数据)与硬件执行模式(按元数据索引跳过零元素)的协同设计。没有元数据,Tensor Core 无法利用稀疏性加速。
2:4 稀疏加速解决的是深度学习模型中权重稀疏性未被充分利用的问题。Tensor Core 内部为此新增了稀疏矩阵索引逻辑,根据 2:4 元数据选择有效元素。权重矩阵经压缩后(仅非零元素+元数据)进入 Tensor Core,减少了 Shared Memory 到 Tensor Core 的数据搬运量。限制在于稀疏化后的模型需满足 2:4 结构约束,任意稀疏模式不被支持,元数据存储也引入额外开销。开发者可观察到满足 2:4 稀疏格式的矩阵乘法吞吐翻倍,不满足格式的稀疏矩阵则无加速效果。
Thread Block Cluster + DSMEM
Thread Block Cluster 和 DSMEM 已在 7.2 和 7.5 中详述。作为 function feature 层面的总结:
Cluster 模式适用于需要高频跨 block 数据交换的算法:并行 FFT(跨 stage 的数据重排)、稀疏矩阵运算(非零元素的跨 block 分发)、图算法( frontier 的跨 block 传播)。在 Ampere 上,这些通信需经 Global Memory,延迟和带宽开销高。Hopper 的 DSMEM 提供了低延迟的替代路径。
Cluster 的启动方式:kernel 启动时指定 cluster_dims(x, y, z),CUDA runtime 将 Cluster 内 CTA 调度到同一 GPC。Cluster 内 CTA 通过 cluster.sync() 同步,通过 DSMEM 直接交换数据。
MIG 2.0
MIG 2.0 已在 7.2 中简要描述。其主要改进是 Confidential Computing 支持:每个 MIG 实例在 TEE 中运行,内存加密和访问控制确保实例间数据隔离。这是数据中心多租户场景的必备能力。
7.7 小结
Hopper 的设计可以用一句话概括:"以数据流为中心,计算与通信在片内紧密耦合"。三条主线贯穿各模块:
精度下沉与数值管理:FP8 将矩阵运算的算术密度进一步提升,但低精度的数值稳定性问题通过 Transformer Engine 的 dynamic scaling 机制解决。硬件并非自动完成"智能选择",而是软件库根据每层数值分布执行确定性 heuristics:硬件提供 FP8 运算能力和 amax 统计,软件负责缩放因子的计算和精度切换决策。
数据移动从线程驱动转向硬件引擎驱动:TMA 将高维张量搬运从线程的 LSU 路径卸载到专用 DMA 引擎,线程仅需提交 descriptor 即可继续计算。这减少了地址计算的 ALU 占用和指令发射压力,数据移动与计算的重叠度因此提升。Transaction barrier 为批量异步传输提供了字节级完成语义。
CTA 边界从 SM 内扩展到 GPC 内:Thread Block Cluster + DSMEM 打破了传统 CTA 间的通信壁垒,SM 间数据交换通过 GPC 内高速网络直接完成,无需经 HBM 中转。这使更大粒度的并行协作得以实现,将 GPU 片内的有效并行粒度从 SM 级提升至 GPC 级。
关键架构权衡:
- 通用性 vs 专用性:Hopper 增加了大量专用单元(Tensor Core FP8、DPX 单元)和专用指令(TMA、WGMMA),同时弱化了图形固定功能。AI 和 HPC workload 因此获得数倍吞吐提升,但图形渲染等 workload 无法高效运行。核心 SIMT 模型和 CUDA ISA 的兼容性确保了软件生态连续。
- 局部性 vs 带宽:Hopper 采用了"大缓存 + 高带宽显存"的组合策略。L1 从 192 KB 增至 256 KB,L2 从 40 MB 增至 50 MB,HBM3 带宽达 3.35 TB/s。更大的缓存提升片上数据复用率,更高的 HBM 带宽降低 cache miss 时的惩罚。但 RF 容量未增(256 KB/SM)是一个隐性约束:SM 计算吞吐翻倍的同时,每线程平均寄存器资源被稀释,高 register pressure 的 kernel 可能以更低的 occupancy 运行。
- 性能 vs 隔离性:MIG 2.0 的 Confidential Computing 引入内存加密和 TEE 的硬件开销,但这是数据中心多租户商业化的必要条件。安全机制的代价是可接受的,因为没有隔离就没有云部署。
Hopper 在单 die 内部做的事情是:通过精度下沉、异步数据引擎和跨 SM 协作三条路径,将 Ampere 奠定的混合精度计算平台推向更高的有效吞吐。
八、Blackwell (2024-2025)
Hopper 用 FP8 + Transformer Engine 确立了精度下沉路线,用 TMA 把数据搬运从线程侧卸载,并把 CTA 协作扩展到 GPC 内。三条线在 Blackwell 被推到新量级:FP4 需要 Micro-Tensor Scaling 才能保住动态范围,双 die MCM 设计把算力密度推向 reticle 极限之外。但 Blackwell 首先必须被当作两颗不同的芯片来读:GB20x 回应的是实时光线追踪与 Neural Rendering 对着色器执行路径和纹理带宽的压力,GB100/200 回应的是超大规模模型推理对低精度算力密度的贪婪需求。两条线共享统一标量管线与第五代 Tensor Core 的底层 SM 设计,但在 die 级组织、显存类型与互联结构上分歧彻底。
架构定位与产品线拆分
Blackwell 包含至少三个互相关联但物理形态差异极大的硬件实体。理解 Blackwell 的前提是把它们拆清楚:
- RTX Blackwell / GB20x(Compute Capability 12.x):面向图形渲染、游戏、工作站与专业可视化。核心关注点是 RT Core 4th、Tensor Core 5th、Neural Rendering、GDDR7、大容量 L2 Cache。这是全系列的主线之一。
- Data Center Blackwell / GB100/GB200(Compute Capability 10.x):面向 AI 训练/推理、HPC、数据处理。核心关注点是 Tensor Core 5th 对 FP4/FP6/FP8 的支持、MCM 双 die 设计、HBM3e、第二代 Transformer Engine。这也是全系列的主线之一。
- Platform Blackwell / NVL72:由 72 个数据中心 GPU 通过 NVLink Switch 互联构成的机柜级系统,涉及 NVLink、NVSwitch、Grace CPU 互联、rack-scale fabric。全系列不进入该层级,后续最多一句话说明存在这一层面。
GB20x(消费级/工作站独立 GPU)与 GB100/GB200(数据中心计算 GPU)在 SM 微架构上有共享的设计元素(统一 INT/FP 标量管线、第五代 Tensor Core、128-bit 定长指令格式),但在 die 组织、内存层次、互联结构和功能单元配比上差异极大。将三者混成统一叙事会严重扭曲对任何一条产品线的理解。
从微架构演进的角度看,Blackwell 的两条主线分别回应不同的问题:GB20x 回应的是"实时光线追踪 + Neural Rendering 对着色器执行路径和纹理带宽的压力",GB100/200 回应的是"超大规模模型推理对低精度算力密度和内存带宽的贪婪需求"。两者共享的 SM 级改进(如统一标量管线)实际是 NVIDIA 在两条产品线之间复用工程投入的结果,而非这些改进对两类工作负载产生相同的效益。
8.1 ISA
Blackwell ISA 的基线框架自 Volta 以来未发生结构性变化:128-bit 定长指令(16 字节/指令),由 L0i → Decode → Warp Scheduler 的流水线供给,每条指令携带 SASS Control Code 用于同步、掩码与依赖控制。Blackwell 在这一基线上的增量集中在三条路径:低精度张量数据类型的原生支持、Uniform Data Path 的浮点扩展、以及 Cooperative Vectors 的着色器接口。
定长指令格式与指令供给
Blackwell 维持 16 字节定长指令编码,这一选择在 Volta 时代即已固化。定长格式的硬件代价是指令密度低于变长格式(x86 的指令平均长度约 3-4 字节),但收益是 Decode 阶段可以按固定边界切分指令流,无需长度解析逻辑,简化了流水线前端。对于 GPU 这种需要每周期从多个 Warp 中各取一条指令的执行模型,定长格式降低了前端调度逻辑的复杂度。
指令缓存层面,Blackwell 沿用 L0i → L1i 的层级结构。从 GB203 的延迟微基准推断,L0i 的组织方式可能与 Hopper 存在差异,但公开白皮书中未披露具体的分区策略。L0i 命中延迟维持在数个周期级别,L1i 作为后备层覆盖更大的工作集。长着色器程序下的指令供给效率更多依赖于分支行为与指令局部性,而非缓存容量的扩展。
Scoreboard 机制继续承担 Warp 内指令的依赖追踪,SASS Control Code 中的依赖位(dependency bit)与让步位(yield bit)继续指导 Warp Scheduler 的 issue 决策。这一机制自 Maxwell 系统化整合以来,在 Blackwell 上未观察到结构性变化。
FP4 与 Micro-Tensor Scaling
第五代 Tensor Core 对 FP4 的原生支持是 Blackwell ISA 最突出的指令级扩展。FP4 的硬件实现涉及三个层面的变化:数据类型定义、scale metadata 处理管线、以及指令编码。
NVFP4 数据类型采用 2 位指数 + 1 位尾数的格式(E2M1),每个 32-bit 寄存器可打包 8 个 FP4 元素。但 FP4 单独使用时的数值动态范围很窄(约 ±6.0),难以直接表示现代神经网络中常见的权重与激活分布。为此 Blackwell 引入 Micro-Tensor Scaling 技术:每个 128×128 或更大维度的矩阵运算 tile 附带一组 per-block scale factor,硬件在读取 FP4 operand 时自动应用 scaling,在写回 accumulator 时自动反 scaling。Scale metadata 的粒度通常为 32 或 64 元素的向量级(具体粒度取决于 tile shape 配置),由硬件在 Tensor Memory 或 Shared Memory 中并行读取并广播至 Tensor Core 的乘法阵列。
ISA 中新增的 Tensor Core 指令编码了 FP4 operand 的 tile shape(M×N×K 维度)、accumulator precision(FP16 或 FP32)、以及 scale 应用模式。编译器(PTX/SASS)或高层框架(TensorRT-LLM、cuDNN)负责在量化阶段生成与硬件粒度匹配的 scale tensor。从开发者的角度观察,FP4 运算的 API 层面封装了 scale metadata 的管理,但底层硬件确实在 Tensor Core 的 operand path 上增加了 scale 读取 → 广播 → 乘法 的额外流水级。
Micro-Tensor Scaling 的硬件代价在于:每个 Tensor Core 需要额外的 scale metadata 读取端口与广播网络,且 scale factor 的读取时序必须与 FP4 operand 的读取对齐,否则引入 bubble。这一设计的权衡是"用额外的 metadata 带宽与轻微增加的延迟,换取 2× 的参数压缩比(相对 FP8)与对应的有效算力提升"。当 scale metadata 的缓存局部性良好时(大模型推理中通常如此,因为 scale factor 的变化频率远低于权重本身),这一代价被掩盖在 Tensor Core pipeline 的其他延迟中。当 scale metadata 出现 L2 miss 时,开发者可观察到 FP4 kernel 的实际吞吐远低于峰值算力。
Uniform Data Path 的浮点扩展
Blackwell 的 Uniform Data Path 在原有整数与地址计算能力基础上,增加了对标量浮点运算的支持:FMAD、FADD、FMUL、FMIN/FMAX 及浮点-整数类型转换指令。Uniform Data Path 是 Turing 时代引入的、独立于主 32-way 向量管线的 1-way(或有限宽度)标量通路,用于执行 Warp 内所有线程共享的常量计算(如统一地址偏移、循环计数器、常量数组索引)。
在 Blackwell 之前,Warp 级的共享浮点计算必须通过主向量管线执行,占用 32-wide ALU 资源,即使所有 32 个 lane 执行相同的操作。Blackwell 的 Uniform Data Path 浮点扩展允许编译器将这类标量浮点操作调度至 Uniform 通路,释放主 32-way 管线的 issue slot。这一改进的收益场景包括:Neural Rendering shader 中每 Warp 共享的神经网络的 bias/scale 常量计算、光线追踪中间着色器中的统一衰减系数计算、以及图形管线中 uniform buffer 驱动的浮点参数更新。
Uniform Data Path 的物理实现宽度未公开,但从 ISA 语义推断其吞吐远低于主向量管线(每周期 1 个标量操作 vs. 32 个向量操作)。因此它并非用于加速密集浮点计算,而是用于消除主向量管线上低利用率的标量操作 bubble。
Cooperative Vectors
Cooperative Vectors 是 Blackwell 在图形着色器接口层面的扩展,允许 vertex/fragment/compute shader 直接调用 Tensor Core 执行小型矩阵-向量乘法(即"cooperative vector-matrix multiply"操作)。ISA 层面,这对应一组新的向量指令,将 Warp 级别的向量数据送入 Tensor Core,以张量运算的吞吐完成矩阵-向量积,结果写回向量寄存器。
这一扩展的硬件路径是:Warp 的 32 个 lane 各自持有输入向量的一部分 → Operand Collector 聚合 → Tensor Core 以 matrix-vector tile 的形式执行 → Writeback 到向量寄存器。相比传统的逐元素 SIMD 计算,Cooperative Vectors 将神经网络的线性层(fully-connected layer)映射到 Tensor Core 的矩阵乘法单元上,有效利用了 Tensor Core 相对标量 ALU 的数量级算力优势。ISA 中新增的指令编码了输入向量的长度、权重矩阵的地址与布局(row-major/column-major)、以及输出精度。
数据中心线的 ISA 增量
Data Center Blackwell(GB100/200)在 ISA 层面延续了 Hopper 的 DPX(动态规划)指令集与 TMA(Tensor Memory Accelerator)控制指令。DPX 指令用于加速动态规划类算法(如序列比对、图最短路径)中的 min-plus 半环运算,TMA 指令用于在全局显存与 Shared Memory 之间发起异步的多维张量拷贝。硬件解压缩引擎的控制指令也属于数据中心线的 ISA 扩展,允许 kernel 直接指令 GPU 在读取压缩数据流时实时解压(LZ4、Snappy、Deflate 格式),减少 CPU 预处理开销。
8.2 Scheduling
Blackwell 的调度体系在三个层级上均有增量,但各增量针对不同产品线的问题域。按层级拆解,并明确哪些机制属于 GB20x 的 graphics/compute 混合调度优化,哪些属于 GB100/200 的数据中心线程协作扩展。
顶层调度:AI Management Processor (AMP)
AMP 是 RTX Blackwell 的 AI/graphics workload coordination block。官方 RTX Blackwell 白皮书公开说明 AMP 使多个 AI models 可与 graphics workloads 同时共享 GPU。AMP 的主要功能是协调 graphics(graphics queue)与计算(compute queue)任务的资源争用,并与 Windows 的 Hardware Accelerated GPU Scheduling (HAGS) 对接。
不宜写成"替代 GigaThread Engine"或"可通过固件改变时间片策略",这些属于未公开 command processor/firmware 级实现。GigaThread Engine 的具体职能与 AMP 的边界未在官方文档中披露。
AMP 的具体调度算法(优先级反转策略、抢占粒度、时间片长度)由 NVIDIA 驱动/固件封闭管理,开发者无法直接编程。但从可观察的症状推断:当 GPU 同时承载 graphics 与 compute 负载时,Blackwell 相比 Ada 的帧时间稳定性(frame time variance)有所改善,compute kernel 的 tail latency 降低。这归因于 AMP 对 compute queue 的饥饿避免(starvation avoidance)机制。
中层调度:Cluster Launch Control (CLC)
CLC 是 Blackwell(数据中心线,CC 10.0)引入的 cluster/block 级调度控制机制。
具体机制:当一个 SM 上的 CTA 因动态负载不均衡提前完成时,CLC 允许该 SM "夺取"(steal)同一 grid 中尚未被其他 SM 认领的 CTA index。这是软件可见的 work stealing 机制:thread block 可尝试 cancel 尚未开始执行的 thread block 或 cluster,成功后 claim 其 index 并执行 stolen work。
这一机制减少了 grid 执行时间受限于最慢 CTA(straggler)的问题,对负载不均衡的工作负载(如图遍历、稀疏矩阵运算、动态规划)有明显的 tail latency 改善。保留"cancel 未启动 block/cluster、claim index、work stealing、负载均衡"这些公开语义。"SM-to-SM steal network、CTA 状态表"等具体电路结构属于未公开微架构实现,除非有 PTX ISA 或微基准证据。
GB20x 的 graphics/compute 混合调度优化方面,Blackwell 在 SM 内部的 Warp Scheduler 层面改进了图形与计算任务的并发调度路径。具体而言,当 graphics pipeline(vertex shader、pixel shader)与 compute shader 共享同一个 GPU 时,Blackwell 的 Warp Scheduler 能够更灵活地在 graphics warp 与 compute warp 之间切换 issue slot,减少了一方空闲等待另一方的结构性 bubble。这一改进与 AMP 的顶层调度配合,使得 async compute 在 Blackwell 上的实际吞吐更接近理论值。
底层调度:Warp Scheduler 与 SER 2.0
Blackwell SM 内部的 Warp Scheduler 维持每子阵列(sub-partition)一个调度器的组织。由于 8.3 节将详述的标量管线统一,Warp Scheduler 的 issue 逻辑有所简化:每个 sub-partition 每周期至多发射一条标量指令(FP32 或 INT32),无需再在两条独立管线之间进行 issue arbitration。
Shader Execution Reordering (SER) 2.0 继续在 Blackwell 上承担着色器执行重排序的职责。SER 的工作层级是 shader invocation(即 pixel/vertex/ray hit shader 的一次调用),而非指令级。它对发散度高的工作负载(如光线追踪产生的高度发散的 hit shader 调用序列)按空间局部性重新排序,减少 L1/L2 cache thrashing 与 texture sampler 的地址发散。SER 2.0 相对于 Ada 的改进细节未在公开文档中充分披露,但从微架构演进推断,重排序 buffer 的容量与重排序策略的精细化程度有所提升,以匹配 Blackwell 增加的 SM 数量与 RT Core 吞吐。
数据中心线的 Thread Block Cluster 延续
Data Center Blackwell 延续 Hopper 的 thread block cluster 模型。多个 CTA 以 cluster 为单位并发驻留在多个 SM 上,通过 Distributed Shared Memory (DSMEM) 与 cluster-level barrier (cluster.sync()) 实现低延迟协作。一个 CTA 不会被拆分到多个 SM 上执行,cluster 中的每个 CTA 作为一个完整单位驻留在单个 SM 上,CTA 之间通过 DSMEM 进行纳秒级片上数据交换。
TMA (Tensor Memory Accelerator) 继续作为 SM 外部的专用 DMA 引擎,负责在全局显存与 Shared Memory 之间异步搬运多维张量数据。TMA 的独立存在意味着数据搬运与 SM 标量/张量运算可以并行进行,减少 SM 因等待数据而停顿的时间。Blackwell 的 TMA 在 FP4/FP8 数据的异步搬运路径上增加了与 Micro-Tensor Scaling 的配合:TMA 可以在搬运 FP4 tile 的同时读取关联的 scale metadata,并将其放置到 Shared Memory 的预定位置,供后续 Tensor Core 指令直接消费。
关于多 GPU 调度与 NVL72:Blackwell 的 Platform 线(NVL72 等 rack-scale 系统)涉及跨 GPU 的任务调度与负载均衡,属于系统架构而非 GPU die 内微架构(见前言范围说明)。
8.3 Execution Unit
Blackwell SM 内部的执行单元设计有两项主要变化:标量管线的统一(FP32 与 INT32 合并为单一 32-way 通用管线)与专用单元(Tensor Core 5th、RT Core 4th)的功能扩展。前者改变了 SM 的基础算力结构,后者决定了 Blackwell 在 AI 与光线追踪场景中的峰值能力。
FP32 与 INT32 标量管线的统一
Blackwell GB20x 把前代"FP32-only + FP32/INT32"式 datapath 改为 unified FP32/INT32 CUDA core。统一后的物理 core 在某个 clock 内只能选择 FP32 或 INT32 语义之一,因此 Blackwell 提升了许多 INT32 指令的峰值吞吐,但不再提供 Ada 式同一 datapath group 内 FP32 与 INT32 的固定并行组合。
这一设计的工程动机是工作负载特征的变化。在 AI 推理与训练 dominant 的 GPU 使用模式中,计算呈现出阶段性特征:一段密集的张量运算(几乎纯 FP32/FP16,INT32 管线闲置)后接一段地址计算与索引更新(INT32 密集,FP32 管线闲置)。独立双管线的优势(混合类型指令的并行发射)在此模式下难以发挥,反而导致持续的结构冒险(structural hazard)与 Warp 切换开销。统一管线的逻辑是:如果实际工作负载很少同时需要两种类型,不如将晶体管预算投入一条更宽的通用管线,提升每类指令的峰值吞吐,并通过 SM 数量增加与频率提升来弥补 lost 的混合并行性。
具体硬件路径:Decode → Warp Scheduler → Scoreboard Clear → Operand Collector 读取 32 个 lane 的源操作数 → Dispatch Port → 32-way 通用 ALU(执行 FP32 FMA/ADD/MUL 或 INT32 ADD/MUL/SHIFT/LOGIC)→ Writeback → Scoreboard Clear。每周期最多一条标量指令(FP32 或 INT32)离开 Dispatch Port。
对开发者的可观察影响:
- 纯 FP32 密集 kernel:Blackwell 单 SM 的 FP32 吞吐与 Ada 相近(可能略高,取决于频率),但由于总 SM 数量增加(GB202 的 SM 数量相对 AD102 增加约 30-50%),全芯片 FP32 峰值算力提升明显。
- 纯 INT32 密集 kernel:Blackwell 单 SM 的 INT32 吞吐理论上可达 Ada 的约 2 倍(从 16-way 提升至 32-way),全芯片 INT32 峰值算力增长更为明显。
- 混合 FP32+INT32 kernel:如果 kernel 中存在大量 FP32 与 INT32 指令紧密交织,Blackwell 的理论 IPC 相比 Ada 可能下降,因为统一 core 在同一 clock 内只能选择一种语义。实际性能取决于 SASS 指令 mix、warp eligibility、scoreboard、RF/operand collector 供给,以及编译器能否把 FP/INT 紧交织变成更长的同类 instruction burst。开发者可通过指令重排(将同类指令聚集为连续块)来缓解这一问题,让 Warp Scheduler 在连续多个周期内保持单一类型的发射。
Blackwell 延续了 Ampere/Ada 的整数乘法性能水平,32-way 通用管线支持全速率的 INT32 乘法(每周期 32 次操作),而 IMAD.WIDE 指令支持 64-bit 地址生成与宽整数乘法,减少了多指令序列的需求。
第五代 Tensor Core
Blackwell 的每个 SM 继续配置 4 个 Tensor Core,升级至第五代。主要增量是对 FP4(E2M1)、FP6 与增强型 FP8 数据类型的支持,以及 Micro-Tensor Scaling 的硬件集成。
Tensor Core 的矩阵乘法管线(MMA pipeline)在 Blackwell 上需要处理更复杂的数据路径:
Global Memory / HBM / GDDR7
↓ (L2 Cache / TMEM)
Tensor Memory / Shared Memory
↓
Operand Collector (FP4/FP6/FP8 tile + scale metadata)
↓
Tensor Core 5th (MMA unit)
↓
Accumulator (FP16/FP32)
↓
Writeback → Register File / Shared Memory
FP4 operand 路径的带宽结构承自 8.1 节的 Micro-Tensor Scaling:Tensor Core 的 operand path 必须并行支持紧凑的 4-bit 权重/激活值与相对稀疏的 per-block scale 两类读取,两者的带宽之比直接决定有效吞吐。
Accumulator precision 的选择是 FP4 运算中的关键权衡。FP4 × FP4 的直接乘积累加若使用 FP4 accumulator,数值误差会迅速累积到不可用。Blackwell 的 Tensor Core 在 FP4 MMA 中使用 FP16 或 FP32 accumulator(由指令编码指定),在运算过程中维持足够的精度范围,仅在最终写回时才可能进行量化。这一设计增加了 accumulator register 的面积与功耗,但确保了 FP4 运算的实际可用性。
Tile shape(M×N×K 维度)的选择影响 Tensor Core 的寄存器占用与 Shared Memory 带宽需求。更小的 tile shape 有利于提高并发度(更多的 tile 可以同时 inflight),但降低了每个 MMA instruction 的算术强度(arithmetic intensity)。Blackwell 的第五代 Tensor Core 在 FP4 精度下支持的 tile shape 配置较 Hopper 的 FP8 路径更为灵活,以适配不同规模的神经网络层。
第五代 Tensor Core 的峰值算力数据(以 B200 为例)在 FP4 精度下可达 Hopper H100 FP8 路径的约 2.5 倍,但这一峰值仅在理想的 data layout、tile shape、无内存瓶颈的理想条件下达到。实际 kernel 中,开发者通常观察到 60-80% 的峰值利用率,瓶颈多在 HBM/GDDR 带宽、TMA 调度延迟或 scale metadata 的缓存局部性上。
第四代 RT Core
Blackwell 的 RT Core 升级至第四代,设计围绕"更大规模的几何体如何更快地遍历与求交"这一问题展开。
三角形簇级别的交叉测试引擎是第四代 RT Core 的关键结构。前代 RT Core 在遍历 BVH 到达叶节点后,对叶节点中的每个三角形逐一进行光线-三角形相交测试。对于由海量微小三角形构成的大规模几何体(Mega Mesh 场景,如高精度数字孪生、电影级资产实时化),叶节点可能包含数千个微小三角形,逐一测试的遍历代价极高。Blackwell 的 RT Core 引入了簇级别的交叉测试引擎:BVH 的叶节点不再指向单个三角形,而是指向一个由多个三角形组成的"簇"(cluster),RT Core 的硬件电路可以一次性对该簇进行包围盒测试与初步裁剪,快速剔除未命中簇,对命中簇再进行三角形级别的精细测试。
这一结构的硬件代价是 BVH 构建时需要额外的簇化步骤(clustering),且簇化的质量直接影响剔除效率。NVIDIA 的 OptiX 7+ 与 DXR 1.2 API 暴露了支持簇化 BVH 的构建标志。从开发者的角度,使用簇化 BVH 时,Blackwell 在处理 Mega Mesh 场景时的光线追踪帧时间相比 Ada 降低 2-3 倍(取决于几何体的簇化友好度),而未使用簇化 BVH 的传统场景中提升幅度有限。
线性段逼近细分曲面是第四代 RT Core 的另一项几何处理优化。对于 Catmull-Clark 细分曲面等参数化几何体,前代架构需要在 shader 中动态细分(tessellation)为三角形后再送入 RT Core。Blackwell 的 RT Core 4th 增加了硬件支持的线性段逼近(linear segment approximation)路径:在遍历阶段,RT Core 可以直接对细分曲面的 patch 进行线性段包围盒测试,以线性几何近似替代完整的曲面求交,减少了 shader 介入与中间几何体生成的开销。这一路径的收益在高度细分的光滑表面上最为明显。
RT Core 4th 的光线-三角形相交测试吞吐相比 Ada 提升约 2 倍,结合簇级测试引擎,综合 RT 性能提升在典型游戏场景中约 1.5-2 倍,在 Mega Mesh 场景中可达 2-3 倍。
纹理单元与点采样吞吐
Blackwell GB20x 的全芯片纹理过滤单元(Texture Filtering Unit)数量相比 Ada 增加约 33%:GB202(RTX 5090)配置约 680 个纹理单元,相比 AD102(RTX 4090)的 512 个增加约 33%。同时,点采样(point sampling,即无过滤的纹理读取)的吞吐率翻倍。
点采样吞吐翻倍的工程动机来自 Neural Rendering 的需求。随机纹理滤波(Stochastic Texture Filtering, STF)与神经纹理压缩(Neural Texture Compression, NTC)算法需要大量随机定位的点采样来重建纹理细节,而非传统的双线性/各向异性过滤。Blackwell 通过增加点采样端口的数量(而非增加过滤单元的算术能力),直接提升了这些算法的采样吞吐。Filtered sampling(双线性/三线性/各向异性)的吞吐提升幅度小于 point sampling,因为过滤的瓶颈在于算术运算(加权平均)而非采样端口。
对于传统图形渲染,纹理单元数量增加主要提升高分辨率纹理贴图场景中的纹理取样并行度,降低 texture sampler 成为瓶颈的概率。开发者可通过 Nsight Graphics 的 Texture Unit Utilization 指标观察是否从这一改进中受益。
调度单元与 SFU
伴随标量管线的统一,每个 sub-partition 的 Warp Scheduler 发射逻辑简化为每周期至多一条标量指令(无需在 FP/INT 管线间仲裁)。Uniform Data Path 增加了浮点运算能力,SFU(Special Function Unit)维持每 sub-partition 4 个的配置,负责 transcendental 函数(sin/cos/log/exp/rsqrt)与属性插值(attribute interpolation)。
8.4 Register File
Blackwell 的 Register File 容量保持 64K 32-bit registers/SM(256 KB,4×64 KB 子分区),与 Ada 相同。Blackwell tuning guide 给出的公开参数是:CC 10.0 最大 64 warps/SM,CC 12.0 最大 48 warps/SM。RF 为 64K 32-bit registers/SM,max registers/thread 为 255,max thread blocks/SM 为 32。
寄存器占用约束应写成公式:
active_warps <= floor(65536 / (regs_per_thread × 32))
再叠加 block limit、shared memory limit、cluster limit。CC 10.0 若要满 64 warps,平均寄存器预算约 32 regs/thread。CC 12.0 若要满 48 warps,平均预算约 42.7 regs/thread。超过这个值不是不能运行,而是 occupancy 下降。
统一标量管线对寄存器利用效率的影响
Blackwell 的统一 INT/FP 管线虽不直接改变 Register File 的物理结构,但通过减少 Warp 切换频率间接优化了寄存器资源的有效利用。
在前代架构(Ampere/Ada)中,当某个 Warp 的指令流在一段时间内密集使用 INT32 管线(如大量指针运算、数组索引)而 FP32 管线闲置时,Warp Scheduler 为填满 FP32 管线的 issue slot,会主动切换至另一个以 FP32 指令为主的 Warp。这种切换引入了额外的寄存器占用:两个 Warp 的上下文同时驻留在 Register File 中,增加了 register pressure。如果 Register File 成为瓶颈,Occupancy 被迫降低。
Blackwell 的统一 32-way 管线消除了这一问题的根源:单个 Warp 在连续执行 INT32 指令时可以占满整个 32-way 管线,Warp Scheduler 无需为了填满闲置管线而引入额外的 Warp 并发。在 INT32 密集的场景(如地址计算繁重的 kernel)中,这表现为更少的 Warp 切换次数与更高的有效 IPC。
IMAD.WIDE 与 64-bit 地址计算
Blackwell 增强了 IMAD.WIDE 指令的硬件支持,允许在单条指令中完成 64-bit 地址生成(32-bit base + 32-bit offset 的乘加运算,产生 64-bit 结果)。前代架构中,64-bit 地址生成通常需要 2-3 条指令(IMAD.HI + IADD 或类似序列),占用多个 issue slot 与临时寄存器。IMAD.WIDE 的引入减少了对临时寄存器的占用(无需存储中间结果的 32-bit 半字),降低了 register pressure。对于频繁进行 64-bit 指针运算的 kernel(如大规模稀疏数据结构遍历),这一改进可观察到 register usage 下降 1-2 个寄存器/线程,进而允许更高的 Occupancy。
数据中心线的 Thread Block Cluster 效应
Data Center Blackwell 延续的 thread block cluster 模型对 Register File 的压力有间接缓解作用。Cluster 允许将一个大型协作任务拆分到多个 SM 上,每个 SM 只承担一部分 CTA,每 CTA 的线程数与寄存器需求可能因此降低。例如,一个需要 1024 线程与大量寄存器的 kernel 在单 SM 执行时可能受限于 256 KB Register File 而无法达到理想 Occupancy。通过 cluster 拆分为 4 个 256 线程的 CTA 分布在 4 个 SM 上,每个 SM 的寄存器压力降低,整体 cluster 的并行度反而提升。
8.5 Memory Subsystem
Blackwell 的内存子系统必须从两条产品线分别讨论。GB20x 与 GB100/200 在 L1/Shared Memory 层级有相似的 SM 级参数,但在 L2 Cache 组织、外部显存类型与 die 级结构上截然不同。混为一谈会掩盖两者面临的不同瓶颈与优化方向。
RTX Blackwell / GB20x 的内存子系统
L1/Shared Memory:每个 SM 的 L1 数据缓存与 Shared Memory 保持 128 KB 可配置空间,与 Ampere/Ada 一致。该空间在 L1 缓存与 Shared Memory 之间按 kernel 需求划分(通过 CUDA API 或编译器指令指定),不同划分比例下的 L1 命中延迟保持恒定。L1/Shared Memory 的总带宽维持 128 字节/周期,单 SM 本地带宽未变。全芯片 L1 总带宽的提升来自 SM 数量增加与频率提升。
L2 Cache:GB202(旗舰芯片)的 L2 Cache 容量为 128 MB,RTX 5090 SKU 为 96 MB。这一容量相比 AD102 同口径增加约 33%(die 对 die:96→128 MB,SKU 对 SKU:72→96 MB),目的是在更高分辨率(4K 及以上)的光线追踪与 Neural Rendering 场景中维持较高的 L2 命中率,减轻对 GDDR7 显存带宽的压力。L2 Cache 的读写带宽约为 8.7 TB/s,但访问延迟约为 130 ns,高于 Ada 架构(AD102)的约 107 ns。
这组带宽与延迟数字有公开的第三方实测支撑。Chips and Cheese 在 RTX PRO 6000 Blackwell (GB202) 上的微基准测得:L2 聚合带宽约 8.7 TB/s,L2 命中延迟从 Ada 的 107 ns 退化到 130 ns 出头。他们在 GB202 die shot 上数出 64 个 L2 cache block,多于 AD102 的 48 个,与容量扩张的推断吻合。一个需要留意的细节是,规模更小的 RTX 5070 的 L2 延迟(122 ns)同样高于 RTX 4090,说明延迟退化不能完全归因于 die 规模放大,下文对延迟上升原因的分析因此需要保留多因素解释的空间。
延迟上升的原因(推断)与 L2 Cache 容量增加导致的片上网络复杂度增加有关:更大的 L2 需要更多的 bank/slice 与更长的互连线,访问路径上的仲裁与路由延迟随之增加。对于延迟敏感但 cache 友好型的工作负载(如小规模矩阵运算),130 ns 的 L2 延迟可能部分抵消带宽提升的收益。对于带宽受限型工作负载(如高分辨率纹理采样、大批量光线追踪遍历),8.7 TB/s 的带宽增益更为关键。
GDDR7:GB20x 采用 GDDR7 显存,相比 GDDR6X 的主要改进是 PAM3 信号编码(替代 GDDR6X 的 PAM4),提供更高的每 pin 数据率与更好的信号完整性。GDDR7 的峰值带宽(以 RTX 5090 的 512-bit 接口为例)约为 1.8 TB/s,相比 RTX 4090(GDDR6X,384-bit,1.0 TB/s)提升约 80%。GDDR7 的控制器集成在 GPU die 上,与 L2 Cache 通过内部 Crossbar 互联。
Data Center Blackwell / GB100/GB200 的内存子系统
MCM 设计与 NV-HBI:Data Center Blackwell 采用 MCM(Multi-Chip Module)设计,每个计算模块包含两颗 reticle-limited GPU die,通过 NV-HBI(NVIDIA High-Bandwidth Interconnect)连接。NV-HBI 提供约 10 TB/s 的 chip-to-chip 带宽,使两颗 die 在逻辑上表现为单一 GPU,共享统一的物理地址空间并维持缓存一致性。
NV-HBI 是 die 级互联,与 NVLink(GPU-to-GPU 互联)处于不同层级。NV-HBI 的物理实现细节(SerDes 速率、链路数量、协议开销)未完全公开,但从 10 TB/s 的带宽量级推断,其采用宽并行总线(而非 NVLink 的串行链路)加一致性协议引擎的实现方式。两颗 die 的 L2 Cache 在硬件层面保持 coherent:任一 die 的 L2 miss 可能触发对另一 die L2 的 snoop,一致性开销随跨 die 访问比例增加而上升。
HBM3e:Blackwell 数据中心 GPU 采用 HBM3e 高带宽显存。以 Blackwell Ultra(B300 系列)为例,HBM3e 总带宽达到约 8 TB/s,相比 H100(HBM3,约 3.35 TB/s)提升约 2.4 倍。HBM3e 的容量在高端 SKU 上可达 192 GB(单 GPU 逻辑视图),满足大模型推理对参数存储的需求。
TMEM (Tensor Memory):每个 SM 有 256 KB TMEM,是面向 Tensor Core/UMMA 的片上 tensor storage,用于 warp-synchronous storage of intermediate results。TMEM 不是 tens-of-MB 级 L2-like cache,也不是自动权重解压 cache。它用于保存中间 accumulator/tiles,降低 register/shared memory 压力并提升 Tensor Core 数据复用。
硬件解压缩引擎:数据中心 Blackwell 集成了专用的硬件解压缩引擎,支持 LZ4、Snappy、Deflate 等压缩格式。该引擎位于内存控制器附近,允许 GPU 直接从压缩数据流中读取并实时解压,减少了 CPU 预处理与额外显存占用的开销。对于大规模数据分析(如 Spark SQL)与压缩模型权重的加载场景,这一引擎可有效提升有效带宽。
(NV-HBI 以下的系统级互联架构,包括 NVLink、NVSwitch、NVL72 rack-scale fabric,属平台级设计,见前言范围说明。)
8.6 Function Feature
Blackwell 的功能特性分布与其产品线分化一致。GB20x 围绕 Neural Rendering 与实时光线追踪强化图形功能,GB100/200 围绕低精度 AI 推理、Transformer 模型加速与企业级可靠性强化计算功能。
RTX Neural Rendering
Neural Rendering 是 Blackwell GB20x 的主要图形技术方向,具体做法是在传统图形管线的关键环节(光照、着色、纹理重建、后处理)引入小型神经网络作为辅助计算层。Blackwell 为 Neural Rendering 提供的硬件基础包括:
- Cooperative Vectors(8.1 节):允许 shader 直接调用 Tensor Core 执行矩阵-向量乘法,用于神经网络的前向推理。
- 第四代 RT Core(8.3 节):通过簇级交叉测试与 Mega Mesh 支持,提供 Neural Rendering 所需的复杂场景几何体遍历能力。
- 点采样吞吐翻倍(8.3 节):为随机纹理滤波与神经纹理压缩提供采样带宽。
- 大容量 L2 Cache(8.5 节):缓存 Neural Rendering 中频繁访问的神经网络权重与中间特征图。
从硬件路径的角度,Neural Rendering 的执行流程涉及:传统图形管线生成 G-buffer → shader 通过 Cooperative Vectors 调用 Tensor Core 推理小型神经网络(如 DLSS 4 的帧生成模型、光线追踪去噪器、神经材质模型)→ Tensor Core 输出覆盖到图形帧上。这一路径的关键瓶颈在于 Tensor Core 与图形管线之间的数据往返延迟,以及神经网络权重的 L2 cache residency。Blackwell 通过维持 L2 Cache 的大容量(96-128 MB)与 Cooperative Vectors 的低调用开销来缓解这一瓶颈。
FP4 微张量标度
Micro-Tensor Scaling 在系统层面的影响:FP4(E2M1)相对 FP8 压缩比 2:1、相对 FP16 为 4:1,相同 HBM 带宽下 FP4 的有效权重读取吞吐为 FP8 的 2 倍,且 per-block scale factor 使多数大模型推理场景的模型质量可与 FP8 相当(perplexity 损失 < 1%)。
开发者调优的关键点是 scale tensor 的局部性:scale factor 的读取带宽需求相对权重仅 1:16 至 1:32(取决于 block 粒度),在 HBM 带宽预算中占比很小,但一旦 scale tensor 的访问模式不连续、出现 L2/Shared Memory miss,FP4 运算的实际吞吐会急剧下降。优化 FP4 kernel 时需确保 scale tensor 的内存布局与访问模式具有良好局部性。
第二代 Transformer Engine
Transformer Engine(TE)最早在 Hopper 中引入,Blackwell 发展至第二代。TE 并非单一硬件单元,而是硬件(Tensor Core + 专用精度转换电路)、编译器(TensorRT-LLM)与软件框架(cuDNN、NeMo)的协同系统。
TE 的主要功能是在 Transformer 模型的前向与反向传播过程中,自动在不同层之间选择合适的数值精度(FP16/FP8/FP4),并在精度转换点插入硬件加速的 scaling/recasting 操作。Blackwell 的第二代 TE 相比 Hopper 第一代的增量包括:
- FP4 支持:将自动精度选择的范围扩展到 FP4,允许 TE 在带宽受限的层(如大权重矩阵乘法)自动降级至 FP4,在精度敏感的层(如 Softmax、LayerNorm)保持 FP16。
- 增强的 Attention 加速:Blackwell 的 Tensor Core 5th 在处理 Attention 机制(Q×K^T 与 Attention×V 的矩阵乘法序列)时,通过优化的 tile scheduling 与中间结果缓存策略,相比 Hopper 的 FP8 attention path 有约 2 倍的吞吐提升。
- 与 Micro-Tensor Scaling 的集成:第二代 TE 在自动量化流程中生成与硬件 Micro-Tensor Scaling 粒度匹配的 scale tensor,FP4 运算的 scale 管理因此对上层框架透明。
从开发者的角度,TE 的行为通过 cuDNN/cuBLAS 的 API 标志或 TensorRT-LLM 的配置启用,框架自动决定每层使用的精度。但在调试性能瓶颈时,理解 TE 的自动精度选择逻辑有助于诊断"为何某些层未如预期使用 FP4"。通常原因是该层的数值动态范围超出了 FP4 + Micro-Tensor Scaling 的表达能力,TE 保守地回退到更高精度。
硬件解压缩引擎(数据中心线)
Blackwell 数据中心线的硬件解压缩引擎位于内存控制器附近,支持 LZ4、Snappy、Deflate 等格式的实时解压。该引擎的工作路径是:压缩数据流从 HBM 或 PCIe 进入 → 解压缩引擎以多通道并行方式解压 → 解压后的数据直接送入 Shared Memory 或 L2 Cache,无需 CPU 中转。
解压缩引擎让 GPU 可以直接消费压缩格式的数据集(如压缩的 Parquet 文件、压缩的模型权重),有效提升了 HBM 带宽的利用率。例如,2:1 压缩比的数据在通过解压缩引擎后,等效带宽翻倍。对于 Spark SQL 等数据分析 workload,这一引擎可将数据加载阶段的 GPU 利用率从"等待 CPU 解压"的低利用率状态提升至持续计算状态。
RAS 与机密计算(数据中心线)
Blackwell 数据中心线集成了 RAS(Reliability, Availability, Serviceability)引擎与 TEE-I/O(Trusted Execution Environment I/O)机密计算支持。RAS 引擎通过硬件监控数千个信号(温度、电压、ECC 错误率、总线 CRC 错误等),预测潜在故障并触发预防性维护。TEE-I/O 实现 GPU 内存与 NVLink 链路上的实时数据加解密,确保多租户云环境下的数据隔离。MIG(Multi-Instance GPU)在数据中心 Blackwell 上继续支持,允许将单个 GPU 逻辑分割为多个隔离的实例。
这些功能属于企业级可靠性特性,不影响图形或 AI 计算的执行路径,但决定了 Blackwell 数据中心 GPU 在云端部署的可行性。
8.7 小结
Blackwell 并非统一架构,而是 NVIDIA 将图形与数据中心两条产品线的工程投入在 SM 微架构层面进行复用的结果。两条主线面临的约束不同,优化的目标函数不同,共享的仅是最底层的执行单元设计与指令格式。
RTX Blackwell / GB20x 的架构权衡
GB20x 的主要约束是"在单 die、GDDR7 的功耗与成本 envelope 内,同时服务传统图形渲染与新兴的 Neural Rendering"。其关键设计决策包括:
- 统一 INT/FP 标量管线:用单条 32-way 通用管线替代双独立管线,以工作负载的阶段性特征为依据,换取执行单元利用率提升与调度逻辑简化。代价是混合类型指令的并发发射能力丧失,通过 SM 数量与频率补偿。
- 第四代 RT Core 的簇级交叉测试:以 BVH 构建时额外的簇化步骤为代价,换取 Mega Mesh 场景的光线追踪遍历效率。对未使用簇化 BVH 的场景收益有限。
- L2 Cache 容量扩至 96-128 MB:以访问延迟从 107 ns 上升至约 130 ns 为代价,换取更大工作集的片上驻留能力。对高分辨率光线追踪与 Neural Rendering 的 cache 命中率有明显改善。
- 纹理单元数量增加 + 点采样吞吐翻倍:直接服务随机纹理滤波与神经纹理压缩的采样带宽需求,而非传统过滤质量提升。
- GDDR7:以 PAM3 信号编码提供比 GDDR6X 更高的每 pin 数据率,是显存带宽提升的主要物理基础。
Data Center Blackwell / GB100/GB200 的架构权衡
GB100/200 的主要约束是"以 MCM 双 die 设计突破 reticle limit,在 HBM3e 的带宽 envelope 内最大化低精度 AI 算力密度"。其关键设计决策包括:
- MCM 双 die + NV-HBI 10 TB/s:以两颗 reticle-limited die 替代单巨 die,以 10 TB/s chip-to-chip 带宽与跨 die cache coherence 的复杂性为代价,换取逻辑上统一 GPU 的晶体管规模与算力密度。NV-HBI 的 coherence 开销是跨 die 访问的隐性代价。
- Tensor Core 5th 的 FP4/FP6 支持 + Micro-Tensor Scaling:以额外的 scale metadata 读取与广播逻辑为代价,换取 2× 于 FP8 的参数压缩比与有效算力提升。FP4 的实际利用率受限于 scale metadata 的局部性与 HBM 带宽。
- 第二代 Transformer Engine:硬件-编译器-框架协同的自动精度管理系统,将 FP4 的复杂度对上层框架透明化,但引入了精度选择保守性导致的潜在算力浪费。
- HBM3e ~****8 TB/s:相比 H100 的 3.35 TB/s 提升约 2.4 倍,是大模型推理带宽瓶颈的主要缓解手段。TMEM 作为片上缓存进一步减少对 HBM 的重复访问。
- 硬件解压缩引擎:将数据处理(解压)集成到 GPU 内存路径中,减少 CPU-GPU 数据搬运,提升 HBM 等效带宽。
Platform Blackwell
由 NVLink Switch 互联的 72-GPU NVL72 机柜级系统代表了 NVIDIA 将设计单位从 die 扩展到 rack 的战略方向,属系统架构与平台工程范畴(见前言范围说明)。
九、总结与展望
从 Tesla(2006)到 Blackwell(2024),每一代都继承了前一代的特定瓶颈,并通过结构性变更在成本之间进行置换。
9.1 代际瓶颈演变
Tesla 用统一 Shader Array 消除了 Vertex/Pixel 物理分离导致的利用率碎片化,代价是全硬件 Dynamic Scoreboard 追踪每个在飞 Warp 的依赖,控制逻辑面积和功耗可观。
Fermi 引入 L1/L2 Cache 层级与 Dual Warp Scheduler,使通用计算负载的存储行为首次可预测,但 GF100 的 16 SM 加新 Cache 层级把 40nm 芯片的散热预算顶穿,控制逻辑面积侵蚀了执行单元的晶体管预算。
Kepler 把固定延迟的 Hazard 检测交给编译器(Control Word),Hardware Scoreboard 缩到只处理可变延迟操作,腾出面积扩展到 192 CUDA Core / SMX。代价是编译器-硬件契约的脆弱性:编译器必须精确知道每条指令变体的延迟,微架构变化需要编译器同步更新。
Maxwell 用四象限 SM 消除跨分区布线,SCHI 嵌入指令编码进一步压缩调度硬件,产生了截至当时最高的面积效率。代价是取消 Hot Clocking 后单 SM 每周期吞吐下降,必须靠更多 SM 补偿。
Pascal 执行 GP100/GP10x 架构分叉,GP100 的 HBM2 + NVLink 打破 HPC 带宽瓶颈,GP10x 的 GDDR5X 为图形和推理优化成本。分叉造成持续至今的产品线复杂度:SM 配置在 FP64 比例、存储层级组织、指令延迟特性上都不同,针对一种变体优化的代码在另一种上利用率不足。
Volta 的 ITS 为每个线程分配独立 PC 与 Call Stack,解决了 SIMT Divergence 问题;第一代 Tensor Core 为矩阵操作建立专用数据通路。代价是逐线程 Context Storage 增加,128-bit 定长指令格式增加了 I-Cache 压力。
Turing 的并发 INT/FP Pipeline 让地址计算与数据计算重叠,RT Core 以固定功能流水线加速 BVH 遍历。RT Core 的收益对 Primary Ray 和 AO 最高,非相干光线下遍历发散使访问串行化,性能急剧下降;分离的 INT Pipeline 在纯 FP 负载下利用率不足。
Ampere 的 Structured Sparsity 在剪枝模型上将矩阵吞吐翻倍,Async Copy 减少了 CUDA Core 在存储移动中的参与。GA100/GA10x 的分化比 Pascal 更深,GA100 减少的图形固定功能能力使其不适合图形密集型负载。
Hopper 的 TMA 消除了张量存储操作的地址生成开销,DSMEM + Thread Block Cluster 实现跨 CTA 直接通信。setmaxnreg 允许运行时动态权衡寄存器和 Occupancy。代价是图形固定功能能力相对降低,TMA 描述符管理增加软件复杂度。
Blackwell 把分离的 INT/FP Pipeline 统一为可逐周期选择数据类型的通用 CUDA core,消除 AI 负载的相位空闲低效。FP4 + MTS 将精度-吞吐权衡推到 4-bit,SER 2.0 以软硬件协同应对光线发散。代价是失去图形负载受益的 INT/FP 并发,FP4 的窄动态范围限制适用性。
调度机制:Dynamic、Static 与 Hybrid
调度硬件经历了三个不同阶段的演变,驱动因素是依赖追踪的成本。
Fermi(全硬件 Dynamic Scheduling): Fermi 的 Scoreboard 在指令级别动态追踪所有依赖,提供最大的运行时灵活性,硬件自动适应 Cache Hit/Miss 的变化,但每个 SM 消耗可观的面积和功耗。
Kepler/Maxwell/Pascal(编译器驱动 Static Scheduling): Control Word / SCHI 将固定延迟的 Hazard 检测转移到编译器,Hardware Scoreboard 缩减为仅处理可变延迟操作(Memory Load、Texture Operation、Barrier)。二者构成职责划分:固定延迟 Hazard 归编译器,可变延迟 Hazard 归硬件。
Volta 至 Blackwell(ITS + 细粒度 Scoreboard): ITS 为逐线程调度重新引入了硬件复杂度,但解决的是不同问题,即 Warp Divergence 而非依赖追踪。Scoreboard 在线程粒度而非 Warp 粒度处理可变延迟存储操作和 Barrier Synchronization,128-bit 定长指令格式携带编译器生成的调度元数据,在更细粒度上维持静态/动态混合。
跨代的不变量是:可变延迟操作无法静态调度。任何具有不可预测存储延迟或同步点的负载都需要 Hardware Interlock。NVIDIA 的调度演进是对哪些操作被视为固定延迟(编译器职责)与哪些被视为可变延迟(硬件职责)的逐步精化。
执行流水线:分离与统一
INT/FP Pipeline 架构根据负载特性振荡。
Volta/Turing(分离 INT/FP Pipeline): 分离整数和浮点执行允许地址计算与数据计算重叠。图形 Pixel Shader 展现这种模式:计算纹理地址(整数偏移计算)同时进行颜色混合(FP 算术)是常见情况。Turing 的 INT32 Pipeline 实现了完全并发,INT 和 FP 指令可以在同一周期从不同 Warp 发出。
Blackwell(Unified INT/FP Pipeline): AI 负载表现出相位行为而非指令级交织。Transformer Inference 在线性层由 FP 矩阵操作主导,然后在 Attention Softmax 和 KV-Cache 查找中进行 INT 为主的索引操作。分离 Pipeline 下,每个相位中另一条 Pipeline 空闲。统一使所有执行资源可以服务于当前活跃的数据类型,提高了利用率但消除了并发性。
权衡关系是直接的:分离利用混合负载中的指令级并发,统一利用跨负载相位的高利用率。"正确"选择取决于主导负载的并行结构。
专用加速单元:面积、验证与利用率风险
每个专用单元(Tensor Core、RT Core、SER、OMM、DMM)都是一次押注:特定操作模式将充分主导未来负载,值得为其分配专用硅片。
Tensor Core(Volta+): 专用矩阵乘加数据通路。硬件成本是矩阵乘法阵列本身(4x4、8x8 或更大 Tile 尺寸的乘加器网格),加上供给它的 Operand Delivery Network。验证成本是确保 Tensor Core 结果与等效 CUDA Core 循环之间的数值等价。利用率风险发生在负载使用的矩阵维度、稀疏模式或数据格式不被该代 Tensor Core 支持时。
RT Core(Turing+): 用于 BVH 遍历和三角形相交的固定功能流水线。硬件在专用逻辑而非可编程 Shader 中实现包围盒相交、基于栈的树遍历和图元相交。面积成本可观,利用率风险在于非相干光线(方向高度发散的光线)会击败遍历 Cache 和存储访问模式的相干性假设。
SER(Turing+): Shader Execution Reordering 通过重排着色工作来应对光线发散。硬件成本是 Reorder Buffer 和调度逻辑,软件成本是识别可重排序工作的 API 复杂度。SER 只在光线发散程度足以导致 Cache Thrashing、但又低到重排序可以恢复局部性的范围内提供收益。
每一代专用单元占芯片面积的比例都在增加。GA100 的 Tensor Core 占 SM 面积比例高于 Volta,Blackwell 的 FP4/MTS 逻辑增加了更多专用化。这一趋势提高了匹配负载的峰值吞吐,也增加了运行无法使用专用路径的负载时的"暗硅"比例。
计算规模与存储层级
从 Fermi 到 Blackwell,计算吞吐与 DRAM 带宽的比例增加了约两个数量级。Fermi 的 L2 Cache 为 768 KB 全芯片共享,Blackwell 的 L2 Cache 达到 128 MB。L2 扩容属于结构性必需:计算吞吐增长(由 SM 数量、Tensor Core 加宽和频率缩放驱动)远超 DRAM 带宽增长(受引脚数量、功耗和信号技术约束)。
Cache 层级的扩展遵循可预测的模式:
- Fermi: L2 作为统一 Cache 引入(768 KB),L1/Shared Memory 每个 CU 可配置
- Kepler/Maxwell/Pascal: L1/Shared Memory 尺寸选项扩展,L2 随芯片变体缩放
- Volta: L1 Cache 与 Shared Memory 统一为单个可寻址结构
- Ampere/Hopper: L2 增长到数十 MB(A100 为 40 MB,H100 为 50 MB)
- Blackwell: L2 在数据中心变体上达到 128 MB
每 MB L2 Cache 消耗的面积本可用于容纳 CUDA Core 或 Tensor Core Lane。选择增加 L2 而非计算,反映的是 Arithmetic Intensity 阈值问题:当每字节 DRAM 加载的操作比例超过存储子系统可支撑的范围时,增加计算单元没有收益。Cache 是硬件对这一带宽-计算失衡的承认。
更大的 L2 增加了 Cache 访问延迟和复杂度。128 MB L2 需要比 768 KB L2 更大的 Tag Array、更多关联路和更长的命中检测路径。这一延迟必须通过增加 Warp 级并行来隐藏,对 Register File 容量和 Occupancy 形成压力。
9.3 未来轨迹
以下观察聚焦于从上述演进中可辨识的微架构趋势,而非平台级产品公告。
精度与数值格式趋势
从 FP32(Tesla)到 FP16(Pascal/Volta)到 TF32(Ampere)到 FP8(Hopper)到 FP4(Blackwell)的进程表明,以精度换取吞吐的驱动力仍在继续。硬件趋势指向更细粒度的缩放机制(Blackwell 的 Micro-Tensor Scaling)来恢复窄格式损失的动态范围。合理的延续是低于 4-bit 的格式配合逐元素或逐块缩放,接近硬件中的二值或三值量化支持。微架构问题是缩放逻辑和精度恢复硬件最终是否会消耗比窄操作数节省更多的面积。
片上存储扩展
L2 Cache 从 Fermi 的 768 KB 增长到 Blackwell 的 128 MB,14 年间增加了 170 倍。这一轨迹反映了计算吞吐与 DRAM 带宽之间不断扩大的差距。未来架构可能继续扩展片上 SRAM,可能通过 3D Stacking 或 Cache-Compute Integration。硬件限制是面积和功耗:SRAM 单元每次访问功耗低于 DRAM,但每位面积更大。在某一点上,用于 Cache 的面积会挤占计算单元,形成新的平衡点。
计算-存储耦合
Hopper 的 TMA 和 Blackwell 的统一 Pipeline 暗示了数据移动与计算更紧密集成的趋势。未来微架构可能将 TMA 概念扩展到更通用的存储访问模式,或将计算逻辑集成到更接近存储阵列的位置(Processing-in-Memory 概念)。约束在于通用程序需要灵活的访问模式,而专用耦合仅对密集张量等可预测结构有效。
竞争格局
三种不同的设计哲学在竞争:NVIDIA 的通用 GPU 加不断增加的专用化、针对特定负载类别优化的超大规模厂商定制硅片(Google TPU、Amazon Trainium)、以及牺牲可编程性换取确定性吞吐的数据流架构(Cerebras、SambaNova)。NVIDIA 的微架构挑战在于吸收有用的专用化(Tensor Core、RT Core、TMA),同时不碎片化编程模型,或在不匹配负载下留下过多暗硅。
9.4 结论
Tesla 到 Blackwell 的演进表明,GPU 架构是一系列硬件约束下的权衡。每一代解决了特定的微架构病态,代价是引入新的病态。Fermi 的 Cache 层级解决了存储不可预测性,但膨胀了控制逻辑。Kepler 的 Static Scheduling 节省了功耗,但造成了编译器脆弱性。Volta 的 ITS 解决了 Divergence,但增加了 Context Storage。Turing 的 INT/FP 分离提高了图形并发性,但在 AI 相位中留下了空闲单元。Blackwell 的统一反转了这一权衡。演进模式并非收敛于某个最优设计,而是对每一代主导负载的持续适应。
跨代分析 GPU 架构时,六个维度构成核心判断基准:目标函数(图形吞吐 / HPC 密度 / AI 训练 / 推理延迟 / 负载融合)、调度粒度(全硬件动态 / 编译器静态 / 混合)、数据流架构(L1/Shared Memory 组织、TMA、DSMEM)、存储与互连(片上 Cache 规模与片外带宽的平衡)、可编程性与专用化(Tensor Core / RT Core 的面积占比与暗硅风险)、产品线分化(单一 SM 设计还是计算/图形分叉)。
附录:跨代架构演进表
以下四张表追踪 NVIDIA GPU 各代的 Compute Capability、调度机制、存储层级和专用执行单元的演进。表格聚焦微架构差异而非产品规格。
Table 1:Compute Capability 演进
| Generation | CC | SM Config (per SM) | Key Datapaths | Process | Introduced |
|---|---|---|---|---|---|
| Tesla (G80/GT200) | 1.0-1.3 | 8 SPs @ 1.35 GHz (Hot Clock) | Scalar SIMT, no L1/D$ | 90/65/55 nm | 2006-2008 |
| Fermi (GF100) | 2.0 | 32 CUDA Cores, 4 SFU, 8 LD/ST | Dual Warp Scheduler, L1/L2$ | 40 nm | 2010 |
| Kepler (GK110) | 3.5 | 192 CUDA Cores (4x48) | Control Word, Static Scheduling | 28 nm | 2012 |
| Maxwell (GM200) | 5.2 | 128 CUDA Cores (4x32) | SCHI, Operand Reuse Cache, Quadrant | 28 nm | 2014 |
| Pascal (GP100) | 6.0 | 64 CUDA Cores, 32 FP64 units | HBM2, NVLink, FP64-heavy SM | 16 nm | 2016 |
| Pascal (GP10x) | 6.1 | 128 CUDA Cores, 4 FP64 units | GDDR5X, FP32-heavy SM | 16 nm | 2016 |
| Volta (GV100) | 7.0 | 64 CUDA Cores, 64 INT32, 8 TC | ITS, 128-bit insn, 1st-gen TC | 12 nm | 2017 |
| Turing (TU102) | 7.5 | 64 CUDA Cores, 64 INT32, 8 TC, 1 RTC | Concurrent INT/FP, Uniform RF, RT Core | 12 nm | 2018 |
| Ampere (GA100) | 8.0 | 64 FP32, 64 INT32, 32 FP64, 4 TC | Async copy, 2:4 Sparsity, 3rd-gen TC | 7 nm | 2020 |
| Ampere (GA10x) | 8.6 | 128 FP32, 64 INT32, 4 TC | Async copy, 3rd-gen TC (no sparsity on all) | 8 nm | 2020 |
| Hopper (H100) | 9.0 | 128 FP32, 64 INT32, 4 TC | TMA, DSMEM, Cluster, FP8, setmaxnreg | 4N | 2022 |
| Ada (AD102) | 8.9 | 128 FP32, 64 INT32, 4 TC | 3rd-gen RT, optical flow | 4N | 2022 |
| Blackwell (GB100) | 10.0 | 128 unified ALUs, 4 TC | Unified INT/FP, FP4/MTS, SER 2.0 | 4NP | 2024 |
| Blackwell (GB20x/GeForce RTX 50) | 12.0 | 128 unified ALUs, 4 TC | Unified INT/FP, FP4/MTS, GDDR7 | 4NP | 2025 |
Table 2:调度机制演进
| Generation | Primary Mechanism | Hardware Scoreboard | Compiler Role | Divergence Handling |
|---|---|---|---|---|
| Tesla | Dynamic HW scheduler | Full dynamic interlock | None (PTX only) | Warp-level PC, serialization |
| Fermi | Dual dynamic scheduler | Full dynamic, per-warp scoreboard | Minimal | Warp-level PC, serialization |
| Kepler | Static + Hybrid | Reduced: variable-latency only | Control Word: fixed-latency stalls | Warp-level PC, serialization |
| Maxwell | SCHI static | Reduced: variable-latency only | SCHI binding, reuse flags | Warp-level PC, serialization |
| Pascal (both) | SCHI static | Reduced: variable-latency only | SCHI + stall counts | Warp-level PC, serialization |
| Volta | ITS + fine-grained scoreboard | Thread-granular for memory/barrier | 128-bit insn: embedded sched info | Per-thread PC, early reconvergence |
| Turing | ITS + fine-grained | Thread-granular for memory/barrier | 128-bit insn: embedded sched info | Per-thread PC, early reconvergence |
| Ampere (both) | ITS + fine-grained | Thread-granular for memory/barrier | 128-bit insn: embedded sched info | Per-thread PC, early reconvergence |
| Hopper | ITS + fine-grained + TMA | Thread-granular + TMA descriptor | 128-bit insn: embedded sched info | Per-thread PC, Cluster-level sync |
| Blackwell | ITS + fine-grained + SER | Thread-granular + SER reorder buffer | 128-bit insn: embedded sched info | Per-thread PC, HW/SW cooperative reorder |
Table 3:存储层级演进
| Generation | L1 Config | Shared Memory | L2 Cache | DRAM Type | Key Innovation |
|---|---|---|---|---|---|
| Tesla | None (TEX only) | 16 KB/SM | None | GDDR3/4 | TEX cache for textures only |
| Fermi | 16-48 KB configurable | 16-48 KB (shared with L1) | 768 KB unified | GDDR5 | First general L1/L2 hierarchy |
| Kepler | 16-48 KB + 16 KB read-only | 16-48 KB (shared with L1) | 1.5 MB | GDDR5 | Read-only data cache |
| Maxwell (GM200/204) | Unified L1/Texture cache + dedicated shared memory | 64-96 KB/SMM (dedicated, not shared with L1) | 2 MB | GDDR5 | Per-block shared limit 48 KB |
| Pascal (GP100) | 24 KB | 64 KB | 4 MB | HBM2 | HBM2: 4096-bit bus |
| Pascal (GP10x) | 24-48 KB | 24-48 KB/96 KB | 2-4 MB | GDDR5X | Higher GDDR datarate |
| Volta | 128 KB unified (L1+SM) | Configurable within 128 KB | 6 MB (V100) | HBM2 | Unified L1/Shared Memory |
| Turing | 128 KB unified | Configurable within 128 KB | 6 MB (TU102) | GDDR6 | Unified structure maintained |
| Ampere (GA100) | 164 KB combined | Configurable | 40 MB | HBM2e | Async copy, large L2 |
| Ampere (GA10x) | 128 KB combined | Configurable | 3-6 MB | GDDR6X | Variable L2 by SKU |
| Hopper (H100) | 256 KB combined L1/shared pool, shared carveout up to 228 KB | Configurable | 50 MB | HBM3 | TMA descriptor cache, DSMEM |
| Ada (AD102) | 128 KB combined | Configurable | 96 MB (full die) | GDDR6X | Large L2 for inference; RTX 4090 SKU: 72 MB L2 |
| Blackwell (B200/GB200, CC 10.0) | 256 KB combined L1/texture/shared pool, shared up to 228 KB | Configurable | 126 MB | HBM3e | TMEM 256 KB/SM |
| Blackwell (GB202 full die, CC 12.0) | 128 KB L1/shared per SM | Configurable | 128 MB (full die) | GDDR7 | RTX 5090 SKU: 96 MB L2 |
| Blackwell (GB203/RTX 5080) | 128 KB L1/shared per SM | Configurable | 64 MB | GDDR7 | — |
Table 4:专用执行单元演进
| Generation | Tensor Core | RT Core | Sparsity Support | Other Specialized Units |
|---|---|---|---|---|
| Tesla-Fermi | None | None | None | PolyMorph Engine (Fermi) |
| Kepler-Maxwell | None | None | None | PolyMorph Engine, Video Codec |
| Pascal | None | None | None | NVLink (GP100), PolyMorph |
| Volta | Gen 1: FP16 4x4x4 MMA | None | None | NVLink 2.0 |
| Turing | Gen 2: FP16/INT8 MMA | Gen 1: BVH traversal + tri intersection | None | NVLink (select SKUs), NVENC/NVDEC |
| Ampere (GA100) | Gen 3: TF32/BF16/FP16/INT8 + 2:4 structured sparsity | None | 2:4 structured (HW skip-zero path) | MIG, NVLink 3.0 |
| Ampere (GA10x) | Gen 3: TF32/BF16/FP16/INT8 + 2:4 (on some) | Gen 2: BVH + tri + motion blur | 2:4 (selective) | NVENC/NVDEC, Optical Flow |
| Hopper | Gen 4: FP8/FP16/TF32 + 2:4 | None | 2:4 structured | TMA, DSMEM, Transformer Engine, NVLink 4.0 |
| Ada | Gen 4: FP16/INT8 (similar to GA10x) | Gen 3: BVH + OMM + opacity micro-maps | 2:4 | SER 1.0, Optical Flow, NVENC/NVDEC |
| Blackwell | Gen 5: FP4/FP6/FP8/FP16 + Micro-Tensor Scaling | Gen 4: BVH traversal + ray-triangle/box + OMM + Mega Geometry / Triangle Cluster Intersection + Linear Swept Spheres | 2:4 + FP4/FP6 fine-grained | SER 2.0 (HW/SW cooperative, not RT Core), NVLink 5.0 |
Table notes: (1) "FP32" and "FP64" refer to single-precision and double-precision floating-point CUDA Cores, respectively. (2) "MMA" denotes matrix multiply-accumulate operations. (3) Tensor Core generation numbers follow NVIDIA's marketing nomenclature but reflect actual hardware capabilities. (4) L1/Shared Memory sizing listed as "combined" where the two are addressed through a unified structure. (5) RT Core capabilities accumulate across generations: Gen 1 = BVH traversal + triangle intersection; Gen 2 adds motion blur; Gen 3 adds Opacity Micro-Maps (OMM); Gen 4 adds Displaced Micro-Mesh (DMM) and SER 2.0.
参考文献
- NVIDIA, "Inside Pascal: NVIDIA's Newest Computing Platform", NVIDIA Technical Blog, 2016. https://developer.nvidia.com/blog/inside-pascal/
- NVIDIA, "NVIDIA Ampere GA102 GPU Architecture Whitepaper v2.0", 2020. https://www.nvidia.com/content/PDF/nvidia-ampere-ga-102-gpu-architecture-whitepaper-v2.pdf
- NVIDIA, "NVIDIA Hopper Architecture In-Depth", NVIDIA Technical Blog, 2022. https://developer.nvidia.com/blog/nvidia-hopper-architecture-in-depth/
- Chips and Cheese, "Microbenchmarking Nvidia's RTX 4090", 2022-11. https://chipsandcheese.com/p/microbenchmarking-nvidias-rtx-4090
- Chips and Cheese, "Nvidia's H100: Funny L2, and Tons of Bandwidth", 2023-07. https://chipsandcheese.com/p/nvidias-h100-funny-l2-and-tons-of-bandwidth
- Chips and Cheese, "Blackwell: Nvidia's Massive GPU", 2025-06. https://chipsandcheese.com/p/blackwell-nvidias-massive-gpu
