新闻中心

EEPW首页 > 智能计算 > 设计应用 > 深度剖析英伟达 Blackwell 架构:张量核心、PTX 指令、SASS、晶圆良率与 GPC 布局

深度剖析英伟达 Blackwell 架构:张量核心、PTX 指令、SASS、晶圆良率与 GPC 布局

作者: 时间:2026-04-01 来源: 收藏

数据中心级 GPUSM100)迎来了数代以来幅度最大的 GPU 微架构革新之一,然而官方至今并未发布详细的技术白皮书。截至目前,面向 AI 负载、针对 UMMATMA  PTX   指令开展的公开布莱克威尔架构微基准测试研究仍属空白。

继《演进:从伏特到布莱克威尔》深度文章之后,半导体分析机构SemiAnalysis 投入了数月工程时间,深入剖析布莱克威尔架构并实测原始 PTX 指令性能,以此确立严谨的实际性能上限,并与理论峰值进行对比。我们旨在揭示计算单元与指令级的硬件吞吐和延迟极限,从机器学习系统与内核开发的角度提供一份实用的性能刻画。测试重点围绕深度学习负载配置展开,例如对主流深度学习库 FlashInfer 中采用的异步内存拷贝方案进行基准测试。

布莱克威尔架构特性

从霍珀(Hopper)到布莱克威尔(),对架构进行了多项增量改进,并针对与 MMA 相关的指令调整了 PTX 抽象层。我们在《英伟达演进》一文中已介绍过其中大部分内容。以下是主要的显著变更:

  • 1 引入张量内存(TMEM) 用于存储 MMA 累加器。线程不再隐式持有 MMA 运算结果,转而由软件在 MMA 作用域内对 TMEM 进行显式管理。
  • 2  tcgen05操作现在由单个线程代表整个 CTA(线程块)发起,而非前代架构中以线程束(warp)或线程束组(warpgroup)为单位。这一点在 CuTe  MMA 原子操作中体现明显:布莱克威尔使用 ThrID =     Layout<_1>,而霍珀基于线程束组的 MMA 则使用 ThrID =      Layout<_128>

  • 3 支持TPC 级别的 TMA以及成对协作 CTA 之间的 MMA,在 PTX 中以 cta_group::2、在  中以 2CTA 形式暴露。组成一个 TPC 的两个 SM 可基于共享操作数执行 tcgen05.mma,通过降低单个 CTA 对共享内存(SMEM)的带宽需求,实现更高运算强度的 MMA 指令。后文将证明,这种操作数共享是充分释放 MMA 吞吐能力的必要条件。
  • 4 原生支持带微缩放(micro-scaling)的子字节精度数据类型。
  • 5 集群启动控制(CLC):为持久 CTA 内核中的动态任务调度提供硬件支持(将在后续文章中详解)。
  • 6 程序化依赖启动(PDL) 在霍珀架构中已引入,用于消除连续内核间的启动与初始化延迟(将在后续文章中详解)。

集群、GPC 布局

 Hopper 架构开始,英伟达数据中心 GPU 就支持一项可选特性,它有多个名称:线程块集群、CTA 集群、协作网格阵列(CGA),这些名称均指向同一功能。集群是 CTA(线程块)的逻辑分组,其形状与大小可按每个内核静态或动态指定。编程模型能感知到集群的存在并实现一些实用功能,例如支持向同一集群内的多个 CTA 执行组播加载—— 我们会在本文后续的 TMA 组播章节详细讲解。

至关重要的一点:同一个集群内的所有 CTA,保证会在同一个 GPC(图形处理集群)上协同调度。这一点对  采用 “ SM 绑定单个 CTA” 的持久 CTA 内核模式至关重要:如果集群大小无法整除 GPC 内的 SM 数量,就会导致部分 SM 闲置。

这一机制很容易让内核开发者困惑:如果不了解文档记载较少的 GPC 机制,开发者往往会简单地按 GPU  SM 数量启动持久 CTA 并开启集群功能,最终导致部分 CTA 只能串行执行。

每个 GPC 最终可用的 SM 数量并非固定值;同一块芯片上不同 GPC 之间可用 SM 数量不同;甚至同一封装内的不同裸片之间,可用 SM 布局也可能不对称。

原因是半导体制造过程中会产生缺陷,这些缺陷可能随机出现在芯片的任何位置。因此,英伟达必须通过架构设计,让这些存在缺陷但仍可工作的单元,以相对统一的方式暴露给软件使用。

我们通过启动不同大小的集群,并利用 PTX 指令中的%%smid记录哪些 SM 被分配到同一个 GPC,以此逆向推导出 SM  GPC 的映射关系。

最终得到了 TPC  GPC 的逻辑分组列表。这个列表的长度超过了 Hopper/Blackwell 标配的 8  GPC,原因是部分 TPC 会独占一个逻辑 GPC,永远不会与其他 TPC 协同调度。

图片

 SM100 架构开始,英伟达针对这种量化分配问题提供了解决方案,使内核既能享受大集群带来的性能优势,又能充分利用所有可用的 SM 计算单元。启动内核时可指定两种集群尺寸:优选集群尺寸与降级集群尺寸。通常情况下,为了完全利用整个 GPU 资源,降级集群尺寸应设置为 2  1

参考资料:

  • 集群 API
  • 协作组 API
  • CU_LAUNCH_ATTRIBUTE_PREFERRED_CLUSTER_DIMENSION

  • CUTLASS 

    示例 73

逻辑 GPC 与物理 GPC

我们上文展示的 TPC  GPC 的分组属于逻辑分组。它们仅代表软件视角下的 GPC 结构,不包含每个 GPC 内部20 个实际物理 SM 中哪些处于启用状态的信息,也不体现每个物理 GPC 在双裸片上的具体位置。

事实上,即便逻辑配置完全相同的 B200 芯片,每个 GPC 中最终可用的物理 SM 数量也不一定完全一致。这可能导致在软件视角看起来完全相同的 GPU 之间,出现性能不确定性的问题。此外,SM  GPC 的逻辑分组信息,也无法区分 B200 封装内的两个裸片分别搭载了哪些 GPC

为了探明 SM 物理布局的更多细节,我们让每个 SM 遍历一个指针追踪数组以填充 L2 缓存,并测量每次加载操作的延迟。针对每个内存地址,我们对比不同 SM 观测到的加载延迟,最终生成SM  SM 之间的距离矩阵(轴和轴均为 SM ID)。

关键术语注释

  1. quantization issue

    (量化分配问题)

集群大小无法整除 GPC  SM 数量,导致 SM 闲置的问题

  1. preferred cluster size / fallback cluster size

优选集群尺寸(高性能优先)降级集群尺寸(兼容性 / 满资源利用优先)

  1. logical GPC / physical GPC

逻辑 GPC(软件看到的分组)物理 GPC(芯片实际硬件布局)

  1. pointer-chase array

指针追踪数组,用于精准测量缓存访问延迟的经典测试方法

图片

我们可以清晰地看到两组独立的 SM 集群,它们之间的 L2 平均访问延迟相差超过 300 个时钟周期—— 这显然就是裸片间(die-to-die)通信的分界。

我们同时用上一节得出的逻辑 GPC 分组对 SM 进行了标注;有趣的是,独立独占的 TPC在延迟上彼此非常接近,且在本次测试中与 GPC0 高度关联,因此可以推测这些 TPC 在物理上就位于 GPC0 内部。

基于这些数据,我们可以进一步修正每个 GPC 实际可用的 TPC 数量列表,不过其中 5+3 的划分仍属于推测。

  • 裸片 A[10, 10, 10, 9]
  • 裸片 B[9, 9, 9, 5+3]

此外,尽管测试方式较为间接,我们仍可得出结论:裸片间访问的延迟开销大约为 300个时钟周期。

这一点在单个 SM 的延迟曲线中也同样明显(曲线中同时包含了大量 L2 拥塞带来的影响)。

图片

在此特别感谢 Decart AI Orian 为本次基准测试提供思路启发。

存储子系统

本节我们介绍存储子系统,也就是在各个计算单元之间搬运数据的硬件单元。内存拷贝指令是使用存储子系统的核心操作,而新一代架构中引入了异步拷贝指令(关于异步机制的演进可参阅前文)。我们重点关注两类异步拷贝指令:LDGSTS TMA(张量内存加速器)。

异步拷贝

异步拷贝(PTXcp.asyncLDGSTS)从安培(Ampere)架构开始引入,该指令可将数据从全局内存异步搬运到共享内存。

异步拷贝是非阻塞的,允许内存加载与计算操作并行执行。它还能直接写入共享内存,无需经过寄存器,从而降低寄存器占用压力。

参考 FlashInfer 的多头注意力(MHA)内核,我们采用以下配置对异步拷贝进行基准测试:

  • 每个 SM  CTA 数量:1234
  • 流水线级数:124
  • 每个 CTA 的线程数:64128256
  • 加载粒度:4B8B16B

我们绘制了吞吐率与每个 SM 的飞行字节数(即并发内存加载指令正在传输的总字节数)的关系曲线。

尽管不同加载粒度在相同飞行字节数下最终能达到相近的吞吐率,但我们更推荐使用 16字节加载。

在相同飞行字节数下,16 字节加载能实现略高的吞吐,同时占用更少执行资源。例如,在 32 KiB 飞行字节时,8B 加载需要 4 级流水线,而 16B 加载仅需 2级。这可以节省两个内存屏障对象所需的存储空间,并降低指令发射压力。

图片

整体来看,LDGSTS 32 KiB 飞行字节数下即可达到饱和,内存吞吐约 6.6 TB/s

我们还针对实际 MLA(多层潜在注意力)内核常用的配置做了基准测试:

  • 每个 SM 1  CTA
  • 16 

    字节加载
  • 每个 CTA 线程数:64128256
  • 流水线级数:481216

实验表明:增加流水线级数能在更高飞行字节数下获得更高吞吐;而提高单个 CTA 的线程数,在所有配置下都能稳定提升性能。

有意思的是,MLA 内核采用 2 个线程束(warp+ 12 级流水线,实测吞吐约 2.2 TB/s。我们认为原因在于:执行 softmax 的线程束需要占用大量寄存器,增加线程束数量会导致单个线程可分配的寄存器减少,从而限制性能。

图片

我们对同一组配置进行了延迟测试。结果显示:

LDGSTS的基线延迟约为600 纳秒,并且在飞行字节数超过 8 KiB 后,延迟几乎翻倍。

原因在于,为了让 LDGSTS 达到高飞行字节数,需要启用大量线程,这会导致大量线程束(warp)因 MIO(内存输入输出)节流 而阻塞。

图片

图片

张量内存加速器(TMA

TMAPTX 指令:cp.async.bulk.tensorSASS 指令:UTMALDG)是在 Hopper 架构中引入的异步数据拷贝引擎,专门用于将大量数据从全局内存搬运到共享内存。只需单个线程即可发起 TMA 操作,完成地址生成、内存交织(swizzling)与越界处理,从而让其他线程可以执行独立任务。

本节我们以 2D 张量版本(cp.async.bulk.tensor.2d)为代表,测试 TMA 的典型使用场景性能。

参照 FlashInfer 注意力内核的设置,我们对 TMA 进行基准测试:每个 SM 只分配一个 CTA,每个 CTA 使用 1~4 个线程束(warp)中的各一个线程,来发起不同块大小的 TMA 指令。下图展示了每种飞行字节数下的最佳吞吐表现。

本次 TMA 测试配置如下:

  • 每个 SM  CTA 数量:1
  • 每个 CTA 的线程数:1284     个线程束)
  • TMA 

    块维度:2D 尺寸从     32×8 逐步增大到 128×128

图片

TMA达到峰值吞吐的时机,要比 LDGSTS晚得多。

异步拷贝与 TMA 对比

 FlashInfer 这样的深度学习内核库会同时使用 TMA 和异步拷贝来加载数据。

TMA与异步拷贝具有不同的性能特点:

  • TMA 

    适合规则访问模式下的大块数据加载,但延迟更高;
  • 异步拷贝则能处理不规则内存访问模式,但存在大小限制。

我们会说明在不同场景下该如何选择。本节针对 FlashInfer  MHA  MLA 内核中实际使用的配置进行了基准测试。

可以看到:

  • 吞吐方面:飞行字节数小于 32 KiB 时,异步拷贝略优于 TMA;超过之后 TMA 迎头赶上,并且能一直扩展到 128      KiB
  • 延迟方面:飞行字节数小于 12 KiB 时,异步拷贝延迟略低于 TMA;超过之后 TMA 延迟会大幅上升。

图片

图片

在实际应用中,Blackwell MLA 内核使用异步拷贝来动态加载页数据,而 MHA 内核则仅使用 TMA

FlashInfer中大部分Blackwell MHA 内核均由 TRT-LLM 贡献,因此我们只能通过反汇编二进制文件来推测内核逻辑。我们发现,与 Hopper 类似,所有 Blackwell TRT-LLM 内核都使用 TMA。我们推测,在动态页加载场景下,这些内核沿用了 Hopper 的设计思路:使用4D TMA,将页索引作为最后一维,并在需要时通过 TensorMap 进行索引寻址。

为了弄清这些内核的确切实现机制,我们呼吁英伟达开源 FlashInfer 中的 TRT-LLM 内核,以惠及整个社区。

TMA组播(Multicast

TMA支持组播模式:单次加载操作可将数据拷贝到多个 SM 的共享内存中,目标范围由 CTA 掩码指定。

组播常用于 GEMM 类计算模式 ——多个 SM 处理不同输出分块时,输入分块可在 SM 间共享。例如在 SwiGLU 激活函数中,两个 GEMM 操作共用同一个输入矩阵,组播就非常适用。

其核心优势在于:

  • 减少 HBM 读取,降低有效带宽占用;
  • 显著减少 L2 流量,因为多个 CTA 对共享数据的请求会被合并为一次请求。

根据 NCU 分析,负责处理 TMA 组播请求的硬件单元称为L2 请求合并器(LRC):

L2请求合并器(LRC)处理到达 L2 的请求,并在转发至 L2 缓存前尝试合并读请求。

该单元同时处理来自 SM 的可编程组播请求,并支持写入压缩。

这意味着即便不显式启用组播,硬件也可能自动表现出类似组播的行为,类似于缺失状态保持寄存器(MSHR)的机制。

为验证这一点,我们运行了同一套 TMA 组播基准测试,但改为所有 CTA 对同一块数据发起独立 TMA 加载,而非由单个 CTA 执行组播加载。

我们对比了三种场景:

  1. 每个 SM 加载不同数据(基准场景)
  2. TMA 

    显式组播 —— 每个集群中一个 CTA 向集群内所有 CTA 执行组播加载
  3. TMA 

    隐式组播 —— 每个集群内所有 CTA 对同一块数据执行普通 TMA 加载

TMA组播能够提供极高的加载带宽以填充 SMEM 缓冲区,即便数据尚未缓存到 L2 中也是如此。

对于已知的流量模式,显式 TMA 组播指令可以完全消除冗余 L2 流量,实现理想的 “每字节 SMEM 数据对应 1 / 集群大小 的 L2 数据流量

我们还观察到,在这一简单测试中,显式与隐式模式下 SMEM 填充带宽几乎一致。但 LRC 并非完美:隐式模式下 L2 仍会产生略多的流量,尤其在总数据量增大时更为明显。

图片

在有效内存吞吐方面,隐式组播与显式组播表现相当。但在降低 L2 缓存流量上,当飞行字节数超过 64 字节后,隐式组播的效果就会明显下降。

分布式共享内存(DSMEM)与本地共享内存(SMEM)对比

英伟达在 Hopper 架构中引入了分布式共享内存(DSMEM)。DSMEM 允许同一个集群内的线程块(CTA)互相访问彼此的共享内存,这对CTA 间归约等计算模式非常实用。但通过 DSMEM 读取对等 CTA 内存的吞吐率,远低于本地 SMEM 每时钟周期 128 字节的峰值。

我们测试了多种访问 DSMEM PTX 指令模式。在编写代码时,DSMEM  SMEM 存在一个关键区别:

DSMEM的加载操作是以数据包形式传输的,与全局内存加载类似。因此,DSMEM 的最优访问模式并非本地 SMEM 中避免存储体冲突的交错访问,而是更像全局内存(GMEM)中典型的连续合并访问。

此外我们发现,若要让本地 SMEM 达到 128 字节 / 时钟的峰值吞吐,必须使用不带 ::cluster 修饰符的 ld.shared 指令。

我们在编写基准测试时就踩过这个坑:直接用 ld.shared::cluster 访问本地和远程共享内存,结果无法达到峰值。

  • 使用     ld.shared 时,编译器会生成专用的 LDS 指令;
  • 而使用     ld.shared::cluster 时,编译器只会生成通用的 LD     指令,无法让本地 SMEM 跑出峰值性能。

我们还发现,ld.shared::cluster 很难进一步提升吞吐;只有切换为cp.async.bulkPTX/ UBLKCPSASS) 后,才能通过单指令搬运更大数据量,让 DSMEM 吞吐获得小幅提升。

以下是我们使用不同 PTX 模式测得的峰值吞吐,单位为字节 / 时钟周期(B/clk),便于与本地 SMEM 的理论最大值对比。

图片

第五代 MMA

MMA指令是执行矩阵乘法的核心操作。从 Hopper  BlackwellMMA性能对矩阵形状的依赖性变得越来越强。

本节我们将深入研究这一现象,通过遍历不同形状与数据类型,量化分析性能差异。

Blackwell新增了 2SM MMA这一全新类型的 MMA 指令(cta_group::2):一对 CTA 会跨两个 SM 协同执行一次 MMA 运算。

具体来说,输入矩阵 A 会被复制,矩阵和矩阵 D 则在两个 SM 间分片,并且这对 CTA 可以互相访问彼此的共享内存。这使得更大规模的 MMA 形状成为可能。

我们将测试 2SM MMA 是呈现弱扩展、强扩展,还是两者兼具。

我们使用以下配置空间对 MMA 性能进行基准测试:

图片

吞吐性能

英伟达针对不同输入数据类型给出了官方标称吞吐指标,本节我们将展示各类(数据格式 + CTA 组)的官方指标,并与实际可达到的最大吞吐进行对比。

结果表明,UMMA 在所有格式与CTA 组配置下均能实现接近理论峰值的吞吐,即便在需要协同开销的 2SM 版本上也是如此。

图片

吞吐性能

在所有 N 尺寸下的 1SM MMA 配置中可以看到:较小的 M=64 仅能达到理论峰值吞吐的 50%,而更大的 M=128 则能接近 100%。这证实 M=64 只利用了一半的数据通路。

 2SM MMA 上,M=128  N=64 时吞吐约为峰值的 90%,在其余所有 N 尺寸下均接近 100%M128N64的吞吐瓶颈应来自 TMEML2SMEM 等其他硬件单元。

与此同时,M=256 在所有配置下都能稳定保持接近 100% 的峰值吞吐,原因是 M=256 对应每个 SM 分摊 M=128,可完整利用数据通路。

我们还发现:相同位宽的数据格式,吞吐表现完全一致;采用微缩放的数据类型几乎没有额外开销。

图片

MMA的两种 AB 布局

MMA支持两种不同的 AB 矩阵存储布局:

  • SS 

    布局:两个输入矩阵都存放在共享内存(SMEM)中
  • TS 

    布局:矩阵 A 存放在张量内存(TMEM)中,矩阵 B 存放在共享内存(SMEM)中

我们观察到,当 M=128时:

  • TS 

    布局在所有 N 尺寸下都能达到接近峰值的吞吐;
  • SS 

    布局在 N 较小时性能偏低,直到 N=128时才追平峰值性能。

图片

我们可以证实,SS 模式下当 N 128 时,指令本身会受到 SMEM 带宽的限制。

举个例子,对于 FP16 精度:

我们知道每个 SM 每周期硬件可执行 8192 MMA FLOPs,而 SMEM 带宽为 128 字节 / 周期(每 SM)。

 M=128N=64K=16为例:

  • 矩阵字节数 = 2 × M × K =      4096 字节
  • 矩阵字节数 = 2 × N × K =      2048 字节
  • 浮点运算量 FLOPs = 2 × M × N × K = 262144

SMEM访问周期 = (A_bytes + B_bytes) / 128 = 48 周期

计算周期 = FLOPs / 16384 = 32 周期

我们逐步增大 N 并计算后发现:

只有当 N ≥ 128 时,指令才真正进入计算瓶颈阶段。

简单总结

  • N < 128

    :受限于共享内存(SMEM)带宽,算力跑不满
  • N ≥ 128

    :受限于计算单元算力,达到理论峰值

图片

其他数据类型也是同理 ——两个操作数都放在 SMEM 中的 MMA 指令,在 N 小于 128 时均受 SMEM 带宽瓶颈限制。

为进一步说明这一点,我们绘制了 FP8 精度下 1SM MMA 所有形状的屋顶线曲线。

可以清晰看到: 262 时处于内存受限区域,曲线斜率约为128 字节 / 周期,正是 SMEM 的带宽上限。

图片

2SM MMA在所有数据格式与矩阵形状下均实现了完美的弱扩展:相比 1SM MMA,在计算资源翻倍的情况下,加速比也恰好达到 2 倍。

而在 SS 布局的小形状矩阵中,我们甚至观察到超过 2 倍的加速比。原因依然是:SS 模式下 N128 时指令受 SMEM 带宽瓶颈限制,而 2SM 版本会将操作数 B 分摊到两个SM 上,从而缓解了带宽压力。

图片

SS模式:当 N  128 时,由于受 SMEM 带宽瓶颈限制,加速比超过 2 倍。

图片

TS模式:接近完美的倍加速。

这些实验表明:在给定的 SMEM 分块大小下,想要获得最大吞吐,应始终使用尽可能大的指令形状。

延迟

我们对单条 MMA 指令的延迟进行了基准测试,并在下图中对比展示。

在所有配置下可以看到:延迟从 N=64  N=128 呈线性上升,而在 N=256 处出现明显陡增,这很可能是因为矩阵维度从 128 跃升到 256 所致。

在单个 CTA 组的 MMA 中:

  • 1SM MMA 

     M=64  M=128 在各 N 尺寸下延迟相近;
  • 2SM MMA 

    中,M=256 的延迟增长略快于 M=128,这与我们的理论估算一致。

对比不同数据类型可见:

  • 1SM MMA 

    下差异很小;
  • 2SM MMA 

    下则出现明显的延迟分化。

图片

我们观察到一个细微但稳定的延迟排序规律:

S8 < BF16 = E4M3 = F4 < MXF8 = MXF4

我们认为,整数运算能效更高,使得 S8 速度最快;而 MXF8  MXF4 因为需要额外计算缩放系数,引入了少量开销。

图片

不同飞行指令数下的吞吐性能

在吞吐基准测试中,我们设置了大量的飞行指令(2561024 条)以摊薄指令发射与提交等待的开销。

但实际内核通常只使用 1条飞行中的 MMA 指令。因此我们专门测试了飞行指令数为 110 时的吞吐,并分析其变化规律。

在所有配置下,相同 N 值与相同MMA 飞行数所达到的理论算力利用率(SoL, Speed-of-Light) 比例相近。

值得注意的是:

  • 只有最大的 N 尺寸能达到 90% 左右的算力利用率;
  • 最小的 N 尺寸仅能达到约 70%

对比 1SM  2SM MMA

  • 1SM 

    的算力利用率比 2SM 高出约 5%

在相同数据格式与相同 CTA 组配置下:

  • 更大的 N 尺寸,吞吐始终高于更小的 N

最后我们观察到:

  • 当飞行 MMA 指令数为 4 时,算力利用率基本封顶在 78%80%

图片

图片

图片



评论


相关推荐

技术专区

关闭