AI 加速器数据供给:SRAM 分 bank 与 NoC 喂数链路设计
更新时间:2026-09-25。上一篇内存墙 HBM 带宽算清了片外的总账:HBM3 每秒 3TB/s 听上去很大,对上百万亿次的峰值算力仍然捉襟见肘。这一篇把镜头推进芯片内部——数据过了 HBM PHY 之后,还要经过全局缓存、片上网络、几十个 SRAM bank,才能最终送到 MAC(乘加单元)的输入寄存器。这条链路上任何一级带宽不够、时序对不齐,阵列就会空转。换句话说,峰值算力写在规格书上,有效算力由喂数链路决定。MAC 单元本身的设计见 MAC 单元与精度设计,阵列如何利用数据复用降低喂数压力,见数据复用与权重固定。
本文要回答的问题
- 为什么说大 MAC 阵列最容易饿死?阵列每个周期到底要吃掉多少字节?
- 片上存储为什么要分成寄存器、本地 SRAM bank、全局缓存三级?bank 数和阵列列宽怎么配?
- mesh NoC(二维网格网络)怎样在 bank 和阵列之间搬权重、激活和部分和?什么是多播?
- 双缓冲(乒乓)和异步 DMA 如何把 HBM 的长延迟藏起来,让阵列一刻不停?
- 从屋顶线视角,片上喂数带宽与算力的配比公式是什么?分块(tile)尺寸为什么必须小于片上 SRAM?
- NoC 拥塞、路径冲突在真实芯片上如何表现,工程上怎么避让?
一、阵列每个周期要吃多少字节
先算阵列的「饭量」。一块 128×128 的 INT8 脉动阵列有 16384 个 MAC,每个 MAC 每周期做一次乘加(2 次运算),跑在 1GHz 时峰值算力约 33 TOPS。它每个周期需要 128 个新激活沿纵向进入、128 个新权重沿横向进入(权重固定流下可少得多,这是后话),即每周期 256 字节,折合 256GB/s 的喂数带宽。这还只是阵列一侧的边:16384 个部分和每若干周期还要读出、做归约。把阵列加大到 256×256、频率提到 1.5GHz,喂数需求就涨到 768GB/s——而单片 HBM3 的总带宽也就 3TB/s 上下,一块阵列就要吃掉四分之一,芯片里通常有十几块这样的阵列。
这就是 AI 加速器数据供给问题的起点:算力随阵列面积二次方增长,而片外带宽只随 HBM 堆栈数线性增长。 阵列越大,单位算力摊到的外存带宽越少。如果把每个操作数都从 HBM 现取,阵列 99% 以上的周期都在等数。工程上的全部应对,可以归纳成两件事:一是让数据在片上被反复复用,一个字节读进来尽量多做几次运算;二是把片外到阵列之间的搬运做成一条持续满载、各级缓冲平滑衔接的流水线。数据复用的四种基本模式(权重固定、输出固定、行固定)在数据复用与权重固定里展开,这一篇聚焦承载复用的硬件链路。
值得强调「饿死」的隐蔽性。阵列不会报错,它只是在等不到操作数的周期插入气泡(bubble),从波形上看就是使能信号拉低。实测芯片中,未经精细调优的工作负载阵列利用率常常只有 20%~40%,差距几乎全部来自喂数断流而非算力不足——这也是为什么数据供给架构是加速器团队的核心 know-how。
二、片上三级存储:寄存器、本地 SRAM bank、全局缓存
数据从 HBM 进入芯片后,要经过三级片上存储,每一级的容量、带宽和能耗各不相同:
| 层级 | 典型容量 | 带宽特征 | 每访问能耗(量级) | 角色 |
|---|---|---|---|---|
| 阵列内寄存器 | 每阵列几十 KB | 每周期全阵列宽,TB/s 级 | 约 0.01~0.05pJ/bit | MAC 直接取数,数据在此被复用 |
| 本地 SRAM bank | 每 bank 64~256KB,16/32 个 bank | 各 bank 并行,合计数百 GB/s | 约 0.2~1pJ/bit | 存当前 tile 的权重/激活,紧邻阵列 |
| 全局缓存(L2) | 几 MB 到几十 MB | 经 NoC 汇聚,数百 GB/s | 约 1~2pJ/bit | 承接 DMA,给 bank 补货 |
这张图对应一次完整的数据循环,读图时抓住两个方向:蓝色下行路径把权重和激活从 HBM 逐级推到阵列,橙色上行路径把部分和逐层归约回 HBM;DMA 引擎横亘在 HBM 与片上之间,是延迟解耦的关键。三级结构之所以必要,是因为带宽和容量天然对立:单块大 SRAM 每周期只能提供一个访问端口、几百 bit 宽度,喂不饱需要每周期数千 bit 的阵列;拆成 16 或 32 个 bank 并行访问,才能凑出阵列边所需的带宽。
bank 划分必须和阵列的列宽严格匹配。128 列的阵列,每个周期一行权重就是 128 字节(INT8),因此每个 bank 的数据位宽常设计为 128 bit 或 256 bit,一次读出刚好是一行或半行操作数;bank 数则按权重和激活同时供给的端口数来定,常见 16 个 bank 服务一块阵列,或 32 个 bank 在两块阵列间共享。地址交织(interleave)让连续 tile 分散落在不同 bank,避免连续访问全挤到同一个 bank 造成 bank conflict——一旦冲突,两个请求串行化,阵列边立刻出现气泡。bank 内的 SRAM 电路本身见 SRAM 单元与灵敏放大器。
能耗账同样驱动分层。寄存器访问最便宜(约 0.01~0.05pJ/bit),所以数据一旦进入阵列就要靠脉动传递反复使用;本地 bank 访问约 0.2~1pJ/bit;每经过一个 mesh 路由跳还要再加约 0.1~0.3pJ/bit 的链路与交换能耗,穿过十几个跳的代价与一次 SRAM 读同量级。因此调度原则是「越近越多用」:能在寄存器里复用的不回 bank,能在本地 bank 消化的不进 NoC。
三、mesh NoC:路由、多播与链路数字
当芯片上有十几块阵列、几十上百个 bank 和缓存分片时,用总线把它们全连起来已不可能,现代 AI 加速器统一采用 mesh(二维网格)NoC:每个节点是一个路由器(router),东西南北各一条链路,数据按 XY 路由(先走 X 方向再走 Y 方向)逐跳转发。NoC 路由器的微结构(输入缓冲、交叉开关、仲裁)在片上网络 NoC 路由器里讲,这里只给系统侧的数字和模式。
典型配置:链路位宽 128~512 bit,频率 0.5~1.5GHz,单条链路单向带宽约 16~96GB/s;一块 8×8 mesh 的对分带宽聚合可达 TB/s 量级。片上网络的拓扑选型、QoS 与死锁规避见 NoC 拓扑 QoS 与死锁。
在 AI 加速器里,NoC 跑的流量有三种,模式差别很大:
| 数据 | 来源与驻留 | NoC 搬运模式 | 复用方式 | 带宽压力 |
|---|---|---|---|---|
| 权重 weights | HBM→L2→权重 bank,卷积核/矩阵分块 | 多播:一份发往多个阵列 tile;层内只读一次 | 同一权重行喂多行激活(权重固定) | 高但被多播摊薄 |
| 激活 activations | HBM 或上层阵列→激活 bank | 单播点对点,沿计算流向相邻 tile 流动 | 同一激活列配多组权重(行固定) | 中,层间流水线可隐藏 |
| 部分和 psum | 阵列→psum bank→归约单元 | 归约树/汇聚单播,向少数归约节点收拢 | 与相邻 tile 部分和相加 | 突发性强,易在归约口拥塞 |
这张图画的是权重多播,也是 AI 加速器 NoC 区别于通用 CPU 缓存网络的最大特点。读图要点:源 bank 只向网络注入一个包,包沿路径走到分叉路由器(图中的 (3,3))才由硬件复制、分发给 tile B/C/D;若不用多播而是四个单播,源节点到分叉点之间的链路要重复走四遍同样的数据。多播把权重流量近似按「路径树」而非「接收者数量」计费,配合权重固定数据流,一份权重行经 NoC 一次就能喂给多行激活,这正是大阵列算力得以兑现的关键机制。实现上要求路由器支持包复制端口和多播路由表,并保证各副本按序到达。
四、双缓冲与异步 DMA:把 HBM 延迟藏进计算时间
HBM 访问延迟有几百个周期,NoC 穿越也要十几到几十跳周期,任何一次「算完了才想起来去取数」都会让阵列停摆数百周期。标准解法是双缓冲(double buffering,也称乒乓)与异步 DMA 的组合。
每个本地 bank 从逻辑上切成 A、B 两面。阵列从 A 面取当前 tile 的操作数时,DMA 引擎并行地把下一个 tile 从 HBM 经 L2、NoC 搬进 B 面;当前 tile 算完,两面角色互换,阵列无缝切到 B 面,A 面开始被补货。部分和侧同理:一面承接阵列写回,另一面由 DMA 排空到归约网络。要做到无缝,条件很直接:搬一个 tile 的时间必须小于算一个 tile 的时间,即 tile 字节数 ÷ 有效供给带宽 ≤ tile 运算量 ÷ 实际算力。算不过这笔账,就增大 tile(多做运算摊薄搬运)或加宽供给通道。
DMA 本身由描述符(descriptor)驱动:编译器或驱动程序一次性排好一条 tile 序列的地址链,DMA 自动链式预取,不需要每 tile 由处理器介入发起,中断和描述符处理开销因此被摊到极薄。DMA 与阵列之间通过信号量或硬件握手标记缓冲面的「满/空」状态,双方完全异步——HBM 的长延迟被吸收进「正在计算」的时间窗内,对阵列表现为零延迟。这就是为什么图一把 DMA 单独画成一级:它不是简单的数据通道,而是整条喂数流水线的节拍器。
用前面的数字走一遍节拍。设单个 tile 在 16 个 bank 上共占 512KB,DMA 经 NoC 把它从 HBM 搬进空面,若这条路径分摊到的有效带宽为 256GB/s,补货耗时约 2 微秒;同一 tile 在阵列上的运算量按复用摊薄后约 12 微秒——补货窗口只有计算窗口的六分之一,即使 HBM 偶尔抖动、NoC 出现几拍排队,双缓冲仍有充足裕量盖住延迟。反过来若把 tile 切得过小,比如只占 64KB,计算时间缩到约 1.5 微秒,补货反而比计算慢,阵列每算完一个 tile 就要空等一拍,利用率被周期性击穿。这个例子说明 tile 尺寸不只是容量问题,它同时决定流水节拍。
工程细节上还有两个常见坑。一是预取距离太短:只预取一个 tile,遇到 HBM 刷新、NoC 瞬时拥塞导致某次补货迟到,双缓冲也救不回来,实际设计常做三级深度的预取队列。二是 A/B 两面必须等宽等容量且地址对齐,否则切换那一面的带宽不足,等于每两个 tile 周期性断流一次。
五、屋顶线、分块与带宽算力配比
把片上链路放进屋顶线框架,结论比片外那篇更细:数据供给存在两级屋顶——HBM 总带宽是第一道,片上 NoC 和 bank 组的供给带宽是第二道,有效算力是两道屋顶下的较小值。阵列峰值算力再高,只要喂数侧供给不足,阵列就运行在带宽斜线以下。
配比公式可以直接写下来。设阵列每周期消费操作数 W 字节、频率 f,其峰值喂数需求为 B_feed = W × f;再设算术强度为 I(每字节做几次运算),则喂满算力所需供给带宽为:
- B_feed ≥ P_peak ÷ I,等价于要求 I ≥ P_peak ÷ B_feed(片上拐点)。
以 128×128 INT8 阵列(P_peak≈33 TOPS,f=1GHz)为例,权重固定下若每个字节平均复用 16 次(I=16),则 B_feed 只需约 33000÷16 ≈ 2TB/s ÷ 1000 ≈ 2GB/s 的净外部供给;但阵列边每周期 256 字节的瞬时需求(256GB/s)必须由本地 bank 满足——这恰好说明两级带宽各自的角色:bank 提供瞬时满宽,外部供给只需补上「复用摊薄后的净流量」。复用率越高,片外带宽压力越小,而复用率由数据流和分块决定。
分块(tiling)是把复用率变成现实的手段。一个卷积层若整块算,中间数据远超片上容量;编译器把它切成 tile,使每个 tile 的权重加激活加部分和恰好小于本地 SRAM:
- tile 尺寸判据:2×T_h×T_w×T_c(激活)+ K×K×T_c×T_f(权重)≤ bank 总字节数。
16 个 128KB bank 提供 2MB 本地容量,INT8 下典型 tile 取 32×32×32 或 64×32×16;tile 越小越放得下,但边界处不能复用的边角数据占比上升、平均复用率下降,因此分块是在容量约束内求复用率最大化的优化问题,由编译器静态搜索。tile 之间在 mesh 上按边界相接的顺序调度,相邻 tile 的重叠 halo 数据只取一次、经 NoC 在两个阵列块间共享。算子融合(把卷积后的归一化、激活函数并进来)进一步保证 tile 的输出部分和不落 HBM,其编译策略见算子融合与编译器。
六、NoC 拥塞与工程权衡
链路位宽和频率给的是空载数字,真实流量下 NoC 会拥塞,这是数据供给设计里最难也最容易在流片后才暴露的一环。
拥塞有三种典型形态。第一种是归约热点:多个 tile 的部分和同时涌向同一个归约单元,通往该节点的链路上路由器缓冲逐级填满,背压(backpressure)沿路径反推,最终卡住阵列写回——表现为阵列在每个归约周期后规律地停几十拍。对策是分散归约点、树形归约,或给部分和流量分配独立的物理网络(不少芯片干脆把 NoC 拆成权重网、激活网、psum 网三张)。第二种是多播与单播路径重叠:权重多播的主干链路同时是某条激活流的必经之路,多播持续占用带宽,单播被饿死;靠虚通道(VC)隔离两类流量并配置 QoS 优先级解决。第三种是全局热点:所有 DMA 在同一时刻朝同一象限补货,mesh 中央链路饱和,平均跳数延迟成倍上升;调度器把 tile 映射到阵列时做空间摊平,让 DMA 源和目的在网格上均匀分布。
设计权衡还包括:加宽链路(512bit)直接抬带宽,但线宽占面积、功耗随翻转率线性增加;加密 mesh 规模能放更多阵列,但对角节点间跳数增大、延迟和每 bit 能耗上升,超过约 10×10 后常改用分簇 mesh 加簇间高速通道;路由器缓冲深度影响突发吸收能力,但缓冲本身是 SRAM、占掉可观面积。所有这些选择最终都回到同一个判据——在目标工作负载的通信轨迹下,阵列边的有效带宽是否持续不低于其饭量,利用率实测数字才是数据供给架构的成绩单。
这一篇在知识体系里的位置
- 想先建立片外带宽的总账与屋顶线推导 → 内存墙 HBM 带宽;
- 想理解权重固定、输出固定、行固定四种复用如何决定带宽压力 → 数据复用与权重固定;
- 想看路由器内部的缓冲、交叉开关与仲裁微结构 → 片上网络 NoC 路由器;
- 想了解拓扑选型、QoS 与死锁规避的完整设计空间 → NoC 拓扑 QoS 与死锁;
- 想看阵列组织与脉动时序的整体架构 → AI 加速器脉动阵列;
- 想看 MAC 单元的电路结构与 INT8/FP16 精度取舍 → MAC 单元与精度设计。
总结
AI 加速器数据供给决定有效算力:128×128 的 INT8 阵列每周期要吃 256 字节、峰值饭量 256GB/s,而算力随阵列面积二次方增长、片外带宽只随 HBM 堆栈线性增长,大 MAC 阵列天然容易饿死;数据必须经「寄存器—16/32 个分 bank 的本地 SRAM(位宽与阵列列宽对齐)—MB 级全局缓存」三级片上层次,由 mesh NoC(128~512bit 链路、0.5~1.5GHz、单链 16~96GB/s)搬运,权重靠多播一份注入、分叉点才复制,激活走点对点、部分和向归约树汇聚;双缓冲乒乓加异步 DMA 描述符预取把 HBM 数百周期的延迟藏进计算窗,无缝条件是「搬一个 tile 不慢于算一个 tile」;配比公式 B_feed≥P_peak÷I 给出两级屋顶,tile 尺寸必须满足权重加激活加部分和不超过 bank 容量,而 NoC 归约热点、多播单播冲突和全局拥塞要靠分网、虚通道 QoS 与空间摊平的调度避让——峰值算力写在规格书上,阵列利用率的实测数字才是喂数链路的真正答卷。