在NPU设计中,存储系统往往是决定整体性能的关键瓶颈。本章深入探讨NPU存储层次设计、数据重用策略、DMA机制以及片上网络基础,帮助读者理解如何通过精心的存储系统设计来最大化NPU的计算效率。我们将以200 TOPS的设计目标为例,定量分析各级存储的带宽需求,并探讨不同数据流模式下的优化策略。
NPU的存储层次通常包含三个主要层级,每层在容量、带宽、延迟和功耗方面都有不同的权衡:
片上SRAM特性
片上SRAM提供最高的带宽和最低的访问延迟,但容量受限且成本高昂。典型参数:
SRAM的物理实现通常采用6T或8T单元结构。6T SRAM单元包含6个晶体管,面积约为0.05 μm²(7nm工艺),而8T SRAM提供独立的读写端口,避免读干扰但面积增加约30%。在NPU设计中,通常采用混合策略:权重缓存使用高密度6T SRAM,而需要频繁读写的激活缓存使用8T SRAM。
SRAM的设计需要在多个维度进行权衡。从电路层面看,降低工作电压可以显著减少功耗,但会增加访问延迟并降低噪声容限。现代NPU通常采用多电压域设计,关键路径上的SRAM运行在标称电压(如0.8V),而非关键路径可以降至0.6V,实现30%的功耗节省。从架构层面看,SRAM的组织方式直接影响访问效率。分布式SRAM设计将存储分散到各个计算单元附近,减少了布线延迟但增加了管理复杂度。相比之下,共享SRAM池提供了更好的容量利用率,但需要更复杂的仲裁机制。
在自动驾驶场景中,SRAM的可靠性尤为重要。软错误率(SER)在先进工艺节点下显著增加,7nm工艺下的SER约为28nm的3-4倍。因此需要采用ECC(Error Correction Code)保护,典型方案是SECDED(Single Error Correction, Double Error Detection),开销约12.5%的额外存储。对于关键数据如神经网络权重,可能需要更强的保护如DEC-TED(Double Error Correction, Triple Error Detection)。此外,老化效应如NBTI(Negative Bias Temperature Instability)会导致SRAM性能随时间退化,需要在设计时预留10-15%的时序裕量。
对于200 TOPS的NPU,假设MAC利用率为80%,nvfp4精度下: \(\text{所需带宽} = 200 \times 10^{12} \times 0.8 \times 3 \times 4 \text{ bits/s} = 1.92 \text{ Pb/s} = 240 \text{ TB/s}\)
其中因子3来自两个输入操作数和一个输出,因子4是nvfp4的位宽。
这个带宽需求远超单片SRAM所能提供,因此需要采用分布式SRAM架构。假设采用1024个SRAM bank,每个bank需要提供: \(\text{Bank带宽} = \frac{240 \text{ TB/s}}{1024} = 234 \text{ GB/s}\)
在1 GHz时钟频率下,每个bank需要234位宽的接口,这在物理实现上是可行的。
HBM技术演进
HBM (High Bandwidth Memory) 提供了容量和带宽的良好平衡:
HBM代际对比:
HBM2E HBM3 HBM3E
带宽 460 819 1230 GB/s/stack
容量 16 24 36 GB/stack
功耗效率 7 5.5 4.5 pJ/bit
I/O宽度 1024 1024 1024 bits
频率 3.6 6.4 9.6 Gbps/pin
电压 1.2 1.1 1.1 V
HBM采用2.5D封装技术,通过硅中介层(interposer)实现与主芯片的连接。每个HBM stack包含8-12层DRAM die,通过TSV(Through Silicon Via)垂直互连。对于200 TOPS的NPU设计,典型配置为4个HBM3 stack,提供总计3.2 TB/s的带宽和96 GB的容量。
HBM的关键优势在于其极短的物理距离(<10mm)和宽I/O接口,相比GDDR6降低了约3倍的pJ/bit访问能耗。然而,HBM的成本约为DDR的5-8倍,且需要先进封装技术支持。
HBM的物理实现涉及多项关键技术。TSV是实现垂直互连的核心,典型TSV直径5-10μm,深度50-100μm,间距40-50μm。每个TSV的寄生电容约20-30fF,电阻约1-2Ω,这些参数直接影响信号完整性。微凸块(micro-bump)技术用于die间连接,间距通常40-55μm,每个凸块可承载约100mA电流。硅中介层采用65nm或更成熟的工艺制造,包含再分布层(RDL)用于信号路由。信号完整性是HBM设计的关键挑战,需要考虑串扰、反射和电源噪声。差分信令和伪差分架构被广泛采用,配合DBI(Data Bus Inversion)减少同步开关噪声。
HBM的控制器设计也颇具挑战。PHY层需要处理1024位宽的并行接口,实现精确的时序校准。训练序列包括ZQ校准、读写时序训练和周期性的重新训练以补偿温度和电压变化。刷新管理采用per-bank刷新或全bank组刷新,刷新间隔通常为3.9μs(高温)或7.8μs(常温)。错误处理机制包括链路层的CRC保护和ECC,典型配置为每128位数据配8位ECC,可纠正单比特错误。温度管理至关重要,HBM3支持实时温度监控和动态频率调节,当结温超过85°C时自动降频。
DDR与GDDR权衡
DDR提供大容量但带宽有限,GDDR则在两者间取得平衡:
在自动驾驶场景中,需要存储大量的高精地图、历史轨迹和中间特征图。一个典型的BEV感知模型可能需要:
因此,边缘端NPU通常采用混合存储架构:
算子带宽需求分析
以矩阵乘法 $C = A \times B$ 为例,计算不同数据流模式的带宽需求:
设矩阵维度为 $M \times K$ 和 $K \times N$,计算量为 $2MNK$ FLOPs。
无重用情况下的理论带宽需求: \(B_{\text{no-reuse}} = \frac{(MK + KN + MN) \times \text{bits}}{2MNK / \text{FLOPS}} = \frac{(M+N+K) \times \text{bits}}{2K} \times \text{FLOPS}\)
引入重用后,实际带宽需求取决于片上缓存大小 $S$:
Output Stationary (OS):缓存输出矩阵块 \(B_{OS} = \frac{2 \times \text{bits} \times \text{FLOPS}}{K}\)
Weight Stationary (WS):缓存权重矩阵块 \(B_{WS} = \frac{2 \times \text{bits} \times \text{FLOPS}}{M}\)
带宽需求的精确建模需要考虑多个因素。首先是数据布局的影响,行主序(row-major)和列主序(column-major)会导致不同的缓存行为。对于矩阵乘法,采用分块矩阵布局(blocked layout)可以改善空间局部性。其次是预取策略的影响,硬件预取器可能会额外加载不必要的数据,导致实际带宽需求比理论值高20-30%。第三是写回策略的影响,write-through策略会立即写回所有修改,而write-back策略只在替换时写回,后者通常更节省带宽。
在实际NPU实现中,带宽利用效率很少能达到理论峰值。造成这种差距的原因包括:访问模式的不规则性导致DRAM页面命中率下降,从典型的70%降至30-40%;读写切换造成的总线周转时间(bus turnaround time),每次切换损失10-20个时钟周期;刷新操作占用的带宽,约7-8%的时间用于DRAM刷新;仲裁和调度开销,特别是在多主设备共享内存时。因此,实际设计中通常需要预留30-40%的带宽裕量。
实际案例:Transformer中的Attention计算
考虑自动驾驶中的多相机BEV Transformer,序列长度 $L = 10000$(100×100的BEV网格),嵌入维度 $d = 256$:
可见,Attention的不同阶段对带宽要求差异巨大,需要动态调整数据流策略。
带宽效率指标
定义带宽效率 $\eta_B$ 为实际计算吞吐量与理论峰值的比值: \(\eta_B = \frac{\text{实际FLOPS}}{\min(\text{计算峰值}, \text{带宽} \times \text{算术强度})}\)
其中算术强度(Arithmetic Intensity)定义为: \(AI = \frac{\text{FLOPs}}{\text{Bytes accessed}}\)
Roofline模型应用
对于200 TOPS NPU,假设HBM带宽3.2 TB/s,构建Roofline模型:
常见算子的算术强度:
可见,depthwise卷积严重受限于内存带宽,而大矩阵乘法则受限于计算能力。
Bank组织结构
典型的多Bank SRAM组织:
┌─────────────────────────┐
│ Crossbar Switch │
└─────┬───┬───┬───┬───────┘
│ │ │ │
┌──▼─┐ │ │ ┌──▼─┐
│Bank│ │ │ │Bank│
│ 0 │ │ │ │ N-1│
└────┘ │ │ └────┘
┌─▼─┐ └─▼─┐
│Bank│ ... │
│ 1 │ │
└────┘ │
Bank数量选择需要平衡面积开销和访问灵活性。常见配置:
多Bank SRAM的设计涉及复杂的微架构决策。交叉开关(crossbar)是连接请求端口和存储bank的关键组件,其复杂度为O(N²),其中N是端口数。为降低复杂度,常采用层次化交叉开关或Benes网络。仲裁逻辑需要在单周期内解决多个访问请求的冲突,常用的仲裁算法包括固定优先级、轮询(round-robin)和矩阵仲裁器。对于N个请求者和M个资源,矩阵仲裁器需要N×M个比较器,能在O(log N)的延迟内完成仲裁。
Bank的物理布局对性能有重要影响。相邻bank之间的布线延迟差异可能导致时序不平衡,需要通过精心的floorplan来优化。H-tree布局是一种常用方案,能够均衡从控制器到各bank的延迟。另一个关键考虑是电源网络设计,大量bank同时切换可能导致严重的电源噪声(IR drop)。解决方案包括交错的bank激活时序、分布式去耦电容和独立的电源域。功耗优化也很重要,未使用的bank可以进入低功耗状态,通过时钟门控和电源门控技术可节省50-70%的静态功耗。
访问模式分析
以2D卷积为例,不同的数据布局导致不同的访问模式:
实际访问模式优化案例
以YOLOv8的C2f模块为例(输入256×80×80,输出256×80×80):
采用NCHW布局时的Bank访问模式:
时刻t: Bank[0]: C0,H0,W0-W15
Bank[1]: C0,H0,W16-W31
...
Bank[4]: C0,H1,W0-W15
问题:当卷积kernel跨行时,会访问Bank[0]和Bank[4],可能造成冲突。
优化方案:
这样可将Bank冲突率从15%降低到2%以下。
冲突消除策略
地址交织(Interleaving): \(\text{Bank}_{\text{id}} = (\text{addr} >> \text{offset}) \bmod N_{\text{banks}}\)
素数Bank数量:选择素数个Bank(如17、31)减少规律性冲突
双缓冲(Double Buffering):计算与数据传输重叠
Bank仲裁器设计
多端口Bank访问需要仲裁机制,常见策略:
仲裁延迟模型: \(T_{access} = T_{arbitration} + T_{bank\_access} + T_{routing}\)
典型值(1GHz时钟):
存储一致性保证
在多个计算单元共享Bank时,需要保证数据一致性:
硬件实现通常采用:
数据重用是提高NPU能效的核心策略。通过最大化片上数据的重用次数,可以显著降低对外部存储器的访问需求,从而减少功耗并提高性能。
时间重用(Temporal Reuse)
时间重用指同一数据在不同时间被同一计算单元多次使用:
\[\text{时间重用度} = \frac{\text{数据使用次数}}{\text{数据加载次数}}\]以矩阵乘法为例,当计算 $C_{ij} = \sum_{k} A_{ik} \times B_{kj}$ 时:
时间重用的效率取决于数据的生命周期管理。在理想情况下,数据应该在其整个使用周期内都保持在片上存储中。然而,有限的片上存储容量要求精心的调度策略。常用的管理策略包括LRU(Least Recently Used)替换、基于重用距离的替换和编译器指导的显式管理。重用距离定义为两次访问同一数据之间访问其他唯一数据的数量,这个指标直接关联到所需的缓存大小。对于规则的访问模式如矩阵乘法,重用距离可以静态分析得出,而对于不规则模式如稀疏矩阵运算,则需要运行时profiling。
时间重用的一个关键优化是循环变换。循环交换(loop interchange)可以改变数据访问顺序,使得重用距离最小化。循环分块(loop tiling)将大循环分解为嵌套的小循环,确保工作集适配缓存大小。循环融合(loop fusion)将多个循环合并,增加数据重用机会。这些变换的合法性需要满足数据依赖约束,可以通过多面体模型(polyhedral model)形式化分析。
空间重用(Spatial Reuse)
空间重用指同一数据同时被多个计算单元使用:
广播数据
│
┌───▼───┐
│ │
┌─▼─┐ ┌─▼─┐
│PE0│ │PE1│ ... │PEn│
└───┘ └───┘ └───┘
空间重用的效率取决于:
重用优化的数学模型
给定片上存储容量 $S$,优化目标是最小化数据传输量 $D$:
\[\min D = \sum_{i} \frac{s_i \times u_i}{r_i}\]其中:
约束条件:$\sum_{i \in \text{on-chip}} s_i \leq S$
具体示例:MobileNet中的Depthwise Separable卷积
考虑MobileNetV3中的一个典型块,输入112×112×24,输出112×112×96:
优化策略:
通过这些优化,可将总数据传输量从8.4 MB降低到2.1 MB,提高4倍性能。
基本Tiling原理
Loop tiling将大的迭代空间分解为小块,使每块的工作集适配片上缓存:
原始循环:
for i = 0 to M-1:
for j = 0 to N-1:
for k = 0 to K-1:
C[i][j] += A[i][k] * B[k][j]
Tiled版本:
for i_outer = 0 to M-1 step T_i:
for j_outer = 0 to N-1 step T_j:
for k_outer = 0 to K-1 step T_k:
// 内层循环处理tile
for i = i_outer to min(i_outer+T_i, M)-1:
for j = j_outer to min(j_outer+T_j, N)-1:
for k = k_outer to min(k_outer+T_k, K)-1:
C[i][j] += A[i][k] * B[k][j]
Tile大小选择
最优tile大小需要满足:
对于计算密度为 $\rho$ FLOPS/cycle 的NPU: \(T_{\text{opt}} = \sqrt{\frac{S \times \rho \times f_{\text{clk}}}{3 \times BW}}\)
其中 $f_{\text{clk}}$ 是时钟频率,$BW$ 是内存带宽。
多级Tiling
针对多级存储层次,采用递归tiling:
L3 Cache Tile: 256×256×256
│
└─► L2 Cache Tile: 64×64×64
│
└─► L1 Cache Tile: 16×16×16
│
└─► Register Tile: 4×4×4
每级的tile大小比例通常遵循: \(\frac{T_{L_{i+1}}}{T_{L_i}} \approx \sqrt[3]{\frac{S_{L_{i+1}}}{S_{L_i}}}\)
Tiling搜索空间优化
对于一个6层嵌套循环的卷积操作(N, C, H, W, K, R, S),tiling参数空间为: \(|\mathcal{S}| = \prod_{i=1}^{7} d_i\)
其中$d_i$是维度$i$的可能分块大小数。对于典型的224×224×256卷积层,搜索空间可达$10^{15}$。
常用优化方法:
解析模型:基于屋顶线模型预测性能 \(T_{exec} = \max(T_{compute}, T_{memory})\)
实践中,通常结合三种方法:解析模型快速筛选,ML模型精细调优,遗传算法处理边缘情况。
Weight Stationary (WS)
权重驻留数据流中,权重保持在PE本地,输入激活和部分和在PE间流动:
特征:
- 每个PE存储部分权重
- 输入激活广播或单播
- 部分和累加并传递
优势:
- 权重重用最大化
- 适合batch size大的场景
- 减少权重读取能耗
劣势:
- 输入/输出数据传输开销大
- 对irregular网络支持差
数学表达: \(\text{数据传输量}_{WS} = \text{Batch} \times (H \times W \times C_{in} + H \times W \times C_{out})\)
Output Stationary (OS)
输出驻留数据流中,部分和保持在PE本地直到完成累加:
特征:
- 每个PE负责特定输出元素
- 权重和激活流经PE
- 部分和本地累加
优势:
- 部分和不需要传输
- 减少累加器带宽需求
- 适合深度网络
劣势:
- 权重和激活重用受限
- PE利用率可能不均
数学表达: \(\text{数据传输量}_{OS} = K \times H \times W \times (C_{in} + C_{out})\)
Row Stationary (RS)
行驻留数据流试图在PE内最大化所有数据类型的重用:
特征:
- 1D卷积原语映射到PE行
- 权重、激活、部分和都有重用
- 灵活支持不同层类型
优势:
- 能量效率最优
- 支持多种数据流模式
- 硬件利用率高
劣势:
- 控制复杂度高
- 编译器映射挑战大
能量模型比较: \(E_{total} = E_{RF} \times N_{RF} + E_{NoC} \times N_{NoC} + E_{DRAM} \times N_{DRAM}\)
其中典型能量成本(45nm):
实际案例:Eyeriss v2的RS数据流实现
Eyeriss v2采用分层式RS数据流,针对不同层类型自适应调整:
能效对比(AlexNet CONV2层):
RS通过灵活的数据流切换,在不同层类型上都能达到较高效率。但代价是控制逻辑复杂度增加约40%,面积开销增加15%。
DMA(Direct Memory Access)是NPU中实现计算与数据传输重叠的关键组件。通过精心设计的DMA系统和预取策略,可以有效隐藏内存访问延迟,提高整体系统性能。
基本DMA架构
现代NPU的DMA控制器通常包含以下组件:
┌─────────────────────────────────────┐
│ DMA Controller │
├──────────┬──────────┬──────────────┤
│ Command │ Address │ Data │
│ Queue │Generator │ Buffers │
├──────────┴──────────┴──────────────┤
│ Arbitration Logic │
└──────────┬──────────────────────────┘
│
┌─────▼─────┐
│ Memory │
│ Interface │
└───────────┘
关键设计参数:
多通道DMA设计考量
在自动驾驶NPU中,不同通道通常专门用于特定数据类型:
通道优先级设置: \(P_i = \alpha_i \times \text{latency\_sensitivity} + \beta_i \times \text{bandwidth\_demand}\)
其中相机数据通道的$\alpha$最高,确保实时性。
带宽分配策略
多通道DMA的带宽分配可建模为优化问题:
\[\max \sum_{i=1}^{N} w_i \times \min(r_i, b_i)\]约束条件:$\sum_{i=1}^{N} b_i \leq B_{total}$
其中:
地址生成模式
支持复杂访问模式的地址生成器:
线性模式: \(\text{addr} = \text{base} + \text{offset} \times \text{stride}\)
2D块模式: \(\text{addr} = \text{base} + x \times \text{stride}_x + y \times \text{stride}_y\)
循环缓冲模式: \(\text{addr} = \text{base} + (\text{offset} \bmod \text{size})\)
3D tensor模式(用于BEV特征): \(\text{addr} = \text{base} + z \times S_z + y \times S_y + x \times S_x\)
其中$S_z = H \times W \times C$, $S_y = W \times C$, $S_x = C$
稀疏索引模式(用于2:4稀疏): \(\text{addr} = \text{base} + \text{index}[i] \times \text{elem\_size}\)
地址生成器的硬件实现
┌─────────────────┐
│ Base Register │
└───────┬─────────┘
│
┌────────┴─────────┐
│ Counter Bank │
│ [X][Y][Z][N] │
└───────┬──────────┘
│
┌────────┴─────────┐
│ Stride Multiply │
└────────┬─────────┘
│
┌────────┴─────────┐
│ Accumulator │
└────────┬─────────┘
│
Final Address
关键优化:
描述符格式
典型的DMA描述符包含:
struct DMADescriptor {
uint64_t src_addr; // 源地址
uint64_t dst_addr; // 目标地址
uint32_t length; // 传输长度
uint16_t src_stride; // 源跨步
uint16_t dst_stride; // 目标跨步
uint8_t burst_len; // 突发长度
uint8_t flags; // 控制标志
uint64_t next_desc; // 下一描述符指针
};
链表管理机制
支持多种链表组织方式:
描述符预取优化:
描述符压缩技术
为减少描述符存储开销,可采用压缩编码:
差分编码:存储与前一描述符的差值 \(\text{desc}_i = \text{desc}_{i-1} + \Delta_i\)
原始:64bit地址 + 32bit长度 + 16bit stride = 112 bits
压缩:32bit基址 + 16bit偏移 + 16bit长度 + 8bit stride = 72 bits
通过这些技术,可将描述符存储开销减少40-60%。
静态预取策略
编译时确定的预取模式:
计算时间线:|--Compute Layer N--|--Compute Layer N+1--|
数据传输: |--Prefetch N+1--| |--Prefetch N+2--|
预取距离计算: \(D_{prefetch} = \lceil \frac{L_{mem}}{T_{compute}} \rceil\)
其中:
动态预取策略
运行时自适应的预取机制:
基于历史的预测: \(\text{addr}_{next} = \text{addr}_{current} + \alpha \times \Delta_{history}\)
基于stride的检测:
双缓冲与流水线
双缓冲机制的时序分析:
Buffer A: |--Load--|--Compute--|--Store--|
Buffer B: |--Load--|--Compute--|--Store--|
时间: 0 T 2T 3T 4T
理想情况下的效率: \(\eta_{pipeline} = \frac{T_{compute}}{\max(T_{compute}, T_{load}, T_{store})}\)
实现200 TOPS的系统,假设:
则需要的预取深度: \(N_{prefetch} = \lceil \frac{100 \text{ cycles} \times 1 \text{ GHz}}{1000 \text{ GFLOPS} / 100 \text{ GB/s}} \rceil = 10\)
预取性能建模
考虑预取准确率和覆盖率:
\[\text{Speedup} = \frac{1}{(1-h) + \frac{h}{1+\alpha \times p}}\]其中:
实际测量数据(ResNet-50):
片上网络是NPU内部各计算单元、存储单元和I/O接口之间的通信基础设施。良好的NoC设计对于实现高效的数据流和低延迟通信至关重要。在200 TOPS级别的NPU设计中,NoC需要提供数百TB/s的聚合带宽,同时保持纳秒级的延迟。
常见拓扑对比
总线(Bus): 环形(Ring): 网格(Mesh):
┌─┬─┬─┬─┬─┐ ┌──┐──┌──┐ ┌──┬──┬──┐
│ │ │ │ │ │ │ └──┘ │ │ │ │ │
└─┴─┴─┴─┴─┘ │ │ ├──┼──┼──┤
│ ┌──┐ │ │ │ │ │
└──┘ └──┘ ├──┼──┼──┤
│ │ │ │
└──┴──┴──┘
Torus(环面): Fat Tree(胖树): Crossbar(交叉开关):
┌──┬──┬──┐ ╱─┴─╲ ┌─┬─┬─┬─┐
│╲ │╱ │╲ │ ╱ ╲ ├─┼─┼─┼─┤
├──┼──┼──┤ ┌─┐ ┌─┐ ├─┼─┼─┼─┤
│╱ │╲ │╱ │ │ │ │ │ ├─┼─┼─┼─┤
├──┼──┼──┤ └┬┘ └┬┘ └─┴─┴─┴─┘
│╲ │╱ │╲ │ │ │
└──┴──┴──┘ PE PE
性能特征比较: | 拓扑 | 直径 | 分割带宽 | 成本 | 扩展性 | 功耗复杂度 | |——|——|———-|——|——–|————| | 总线 | 1 | O(1) | 低 | 差 | O(N) | | 环形 | N/2 | O(2) | 低 | 中 | O(N) | | 2D网格 | 2√N | O(√N) | 中 | 好 | O(N) | | Torus | √N | O(2√N) | 高 | 好 | O(N) | | 胖树 | logN | O(N) | 高 | 优秀 | O(NlogN) | | Crossbar | 1 | O(N) | 极高 | 差 | O(N²) |
拓扑选择的定量分析
对于200 TOPS的NPU设计,需要支持:
拓扑选择的约束条件: \(\text{Cost} = \alpha \times N_{routers} + \beta \times N_{links} + \gamma \times \text{Wire\_length}\)
其中:
以16×16 2D Mesh为例的详细分析:
若每条链路32位宽,运行在2GHz,则: \(BW_{link} = 32 \text{ bits} \times 2 \text{ GHz} = 8 \text{ GB/s}\) \(BW_{bisection} = 16 \times 8 = 128 \text{ GB/s}\)
层次化NoC设计
现代NPU通常采用层次化NoC,结合多种拓扑:
全局NoC (2D Mesh)
│
├───┼───────────┐
│ │ │
▼ ▼ ▼
局部集群 局部集群
(Crossbar) (Ring)
│ │ │ │
PE PE PE PE
层次化设计的优势:
拓扑的物理实现考虑
在7nm工艺下的布线资源:
2D Mesh的物理布局优化:
维序路由(Dimension-Order Routing)
最常用的死锁避免路由算法,先沿X维路由,再沿Y维:
def xy_routing(src_x, src_y, dst_x, dst_y):
# 先X后Y,避免死锁
path = []
# X维路由
while src_x != dst_x:
if src_x < dst_x:
path.append("EAST")
src_x += 1
else:
path.append("WEST")
src_x -= 1
# Y维路由
while src_y != dst_y:
if src_y < dst_y:
path.append("NORTH")
src_y += 1
else:
path.append("SOUTH")
src_y -= 1
return path
XY路由的死锁避免证明:
自适应路由
根据网络拥塞动态选择路径:
\[P_{route} = \arg\min_{p \in \text{paths}} \sum_{l \in p} C_l\]其中$C_l$是链路$l$的拥塞度量,可定义为: \(C_l = \alpha \times Q_l + \beta \times U_l + \gamma \times D_l\)
部分自适应路由算法
Odd-Even路由规则:
这保证了无死锁同时提供路径多样性。
容错路由
处理故障节点和链路的路由策略:
故障节点绕行示例:
┌──┬──┬──┐
│ │ │ │
├──┼XX┼──┤ XX: 故障节点
│ │↗↘│ │ 绕行路径:→↗→
├──┴──┴──┤ →↘→
容错路由的实现:
虚通道(Virtual Channel)
通过多个虚拟通道共享物理链路,提高利用率并避免死锁:
物理链路
┌─────────────────────┐
│ VC0: [████ ] │ 请求消息
│ VC1: [ ████ ] │ 响应消息
│ VC2: [ ████] │ 多播消息
│ VC3: [██ ] │ 逃逸通道
└─────────────────────┘
虚通道分配策略:
虚通道的硬件实现
输入端口结构:
┌──────────────┐
输入 ──> │ VC Demux │
├──────────────┤
│ VC0 Buffer │
├──────────────┤
│ VC1 Buffer │
├──────────────┤
│ VC2 Buffer │
├──────────────┤
│ VC3 Buffer │
├──────────────┤
│ VC Allocator │
├──────────────┤
│ Switch Alloc │
└──────────────┘
│
交叉开关
VC分配的两阶段过程:
分配器的仲裁算法:
信用流控(Credit-based Flow Control)
接收方向发送方发放信用,控制数据发送:
发送方 接收方
┌──────┐ ┌──────┐
│Buffer│ ──data(3 flits)─> │Buffer│
│Count │ <──credit(3)──── │Free │
│=N-3 │ │=3 │
└──────┘ └──────┘
信用计算的详细推导: \(\text{Credits}_{min} = \lceil \frac{\text{RTT} \times BW}{\text{flit\_size}} \rceil + \text{buffer\_depth}\)
其中RTT (Round-Trip Time)包括:
对于2GHz时钟,128位flit的系统:
On/Off流控
更简单但效率较低的流控机制:
时序图:
发送方: |--Send--|--Wait--|--Send--|
接收方: |--Recv--|--OFF----|--ON----|
On/Off流控的阈值设置:
背压机制(Backpressure)
当下游拥塞时,向上游传播停止信号:
\[\text{Throughput} = \min_{i \in \text{path}}(\text{capacity}_i \times (1 - \text{congestion}_i))\]背压传播模型: \(P_{stop}(t+1, n) = \begin{cases} 1 & \text{if } Q_n(t) > T_{high} \\ P_{stop}(t, n+1) & \text{if } Q_n(t) > T_{mid} \\ 0 & \text{otherwise} \end{cases}\)
其中$Q_n(t)$是节点$n$在时刻$t$的队列占用。
弹性缓冲流控(Elastic Buffer)
利用流水线寄存器作为分布式缓冲:
┌──┐ ┌──┐ ┌──┐ ┌──┐
│R1│──│R2│──│R3│──│R4│ 弹性流水线
└──┘ └──┘ └──┘ └──┘
↓ ↓ ↓ ↓
Valid & Ready握手
优势:
延迟模型
端到端延迟的精确建模:
\[L_{total} = L_{header} + \sum_{i=1}^{H}(L_{router,i} + L_{link,i}) + L_{contention}\]各组件延迟分解:
链路延迟: \(L_{link} = \lceil \frac{d}{v_{signal}} \times f_{clk} \rceil\) 其中$v_{signal} \approx 0.5c$(硅中信号速度)
带宽模型
有效带宽的详细分析:
\[BW_{effective} = BW_{physical} \times \eta_{total}\]其中: \(\eta_{total} = \eta_{protocol} \times \eta_{routing} \times \eta_{congestion} \times \eta_{serialization}\)
各效率因子:
热点和拥塞建模
热点形成的概率模型: \(P_{hotspot} = 1 - (1 - p)^N\)
其中$p$是单个节点成为热点的概率,$N$是节点数。
拥塞扩散模型(基于流体动力学): \(\frac{\partial \rho}{\partial t} + \nabla \cdot (\rho \mathbf{v}) = S\)
其中:
实际案例:Google TPU v4的ICI
TPU v4使用3D Torus拓扑的Inter-Chip Interconnect (ICI):
架构参数:
关键优化技术:
性能测试结果(BERT-Large训练):
本章深入探讨了NPU存储系统与数据流设计的核心概念。我们从存储层次设计出发,分析了片上SRAM、HBM和DDR的技术特征与权衡,通过定量计算确定了200 TOPS NPU所需的240 TB/s内部带宽。在数据重用模式部分,我们对比了时间重用与空间重用,详细分析了WS/OS/RS三种数据流的能效特征。DMA设计章节介绍了多通道DMA架构、描述符管理和预取策略,展示了如何通过双缓冲实现计算与传输的重叠。最后,我们深入研究了片上网络的拓扑结构、路由算法和流控机制,并以TPU v4的ICI为例说明了大规模互连的实际实现。
关键要点:
关键公式回顾:
练习4.1 计算存储带宽需求 一个NPU需要执行矩阵乘法 $C_{512×512} = A_{512×768} \times B_{768×512}$,采用nvfp4量化。若计算吞吐量为100 TOPS,MAC利用率80%,计算: a) 无数据重用时的理论带宽需求 b) 采用Output Stationary数据流的带宽需求 c) 若片上SRAM仅32MB,设计合理的tiling策略
练习4.2 Bank冲突分析 一个NPU有16个SRAM bank,采用交织存储,地址映射为 $Bank_{id} = addr \bmod 16$。现需要同时访问地址0x1000、0x1010、0x1020、0x1030,问: a) 是否存在bank冲突? b) 若改为 $Bank_{id} = (addr » 4) \bmod 16$,结果如何? c) 设计一个映射函数避免此类冲突
练习4.3 DMA预取深度计算 一个NPU系统的参数如下:
练习4.4 多级存储优化 设计一个三级存储系统用于Transformer的Attention计算(序列长度8192,头维度64):
练习4.5 NoC路由优化 在8×8 2D Mesh上,从(0,0)发送数据到(7,7),同时存在以下流量:
练习4.6 数据流能效分析 比较三种数据流(WS/OS/RS)在以下场景的能效:
练习4.7 存储一致性设计 设计一个支持多个计算集群共享SRAM的一致性协议,要求:
练习4.8 端到端系统设计 为自动驾驶BEV感知设计完整的存储和NoC系统: