4、AI芯片存储层次:SRAM、HBM/DDR与存储墙
好,咱们今天聊一个绕不开的话题——存储。做AI芯片,说白了就是在跟数据搬来搬去打交道。我入行那会儿,有个老前辈跟我说过一句话,我一直记着:“计算是免费的,数据搬运才是真金白银。” 当时不太理解,后来踩了坑才明白,这话一点不夸张。
4.1 存储墙问题:AI芯片的“心头痛”
先说说这个“存储墙”。你想想看,AI计算的核心是什么?是矩阵乘法和卷积。这些运算本身,芯片算得飞快。但问题来了——数据在哪儿?
数据在内存里。处理器要算一个数,得先去内存里取。取数据的速度,远远跟不上计算的速度。这个速度差,就是“存储墙”。
核心矛盾: 计算单元每时钟周期能完成数千次乘加运算,但片外DRAM的带宽,可能连一次完整的数据搬运都喂不饱。
我在项目中遇到过这样的情况:一个ResNet-50模型,理论算力利用率能做到80%以上,结果实测只有30%。查了半天,发现瓶颈不在计算,而在数据搬运。计算单元大部分时间在“等数据”。说白了,芯片在“饿肚子”。
为什么会这样?因为DRAM的访问延迟是纳秒级的,而SRAM是皮秒级的。差了两个数量级。你想想看,这就像你让一个流水线工人干活,但原材料要等卡车从隔壁城市运过来——大部分时间都在等。
4.2 片上存储:SRAM的“快”与“贵”
SRAM,静态随机存取存储器。它的特点就一个字:快。但代价是面积大、功耗高。在芯片上,SRAM是“寸土寸金”的存在。
我习惯把SRAM分成三个层次:
- 寄存器文件(Register File): 离计算单元最近,容量最小(几十KB),延迟最低(1-2个时钟周期)。
- 共享缓存(Shared SRAM): 通常给多个处理单元共用,容量几百KB到几MB。我在设计NPU时,这块是重点优化的地方。
- 全局缓存(Global SRAM): 芯片上的“大仓库”,容量几MB到几十MB。但访问延迟会高一些。
我的经验: 设计SRAM分配时,别贪大。我曾经为了省事,把全局缓存做得很大,结果发现大部分时间都在做数据搬移,反而浪费了功耗。后来我学乖了——按需分配,够用就好。
4.3 片外存储:HBM与DDR的“带宽之战”
片外存储,就是芯片外面的内存。AI芯片主要用两种:DDR和HBM。
| 类型 | 带宽(典型值) | 容量 | 功耗 | 成本 |
|---|---|---|---|---|
| DDR4/DDR5 | ~50 GB/s | 16-64 GB | 低 | 低 |
| HBM2/HBM2E | ~1 TB/s | 8-32 GB | 中 | 高 |
| HBM3 | ~3 TB/s | 16-64 GB | 高 | 极高 |
HBM的优势很明显——带宽高。它通过硅中介层(Interposer)把多个DRAM die堆叠在一起,用微凸点连接。说白了,就是把内存“贴”在芯片旁边,走线短,速度快。
但HBM也有缺点:贵。而且容量受限。我做过一个项目,客户要求跑大模型,HBM容量不够,最后只能上DDR。嗯,这里要注意——选型时一定要算清楚:你的模型需要多少参数?中间结果有多大?带宽够不够喂饱计算单元?
避坑指南: 我曾经在一个项目里,为了追求极致带宽,选了HBM2E。结果发现,模型太小,带宽根本用不完,白白浪费了成本。后来我学到一个原则:带宽和容量要匹配,别盲目追求高带宽。
4.4 数据复用策略:让数据“多跑几趟”
既然数据搬运这么贵,那怎么办?答案是:让数据在片上多复用几次。
数据复用,说白了就是“一次取进来,多用几次”。AI计算中,数据复用主要有三种模式:
- 输入特征图复用(Input Reuse): 同一个输入特征图,被多个卷积核共享。比如一个3x3的卷积,输入数据会被9个权重复用。
- 权重复用(Weight Reuse): 同一个权重,被多个输出通道共享。这在全连接层里特别明显。
- 输出累加复用(Output Reuse): 多个部分和累加到一个输出上,减少中间结果的写回。
我习惯用“数据流”来设计复用策略。举个例子:
// 伪代码:卷积层的数据复用
for (int oc = 0; oc < OUTPUT_CH; oc++) {
for (int ic = 0; ic < INPUT_CH; ic++) {
// 权重从SRAM中读取一次,被多个输出位置复用
weight = sram_weight[oc][ic];
for (int h = 0; h < HEIGHT; h++) {
for (int w = 0; w < WIDTH; w++) {
// 输入特征图从SRAM中读取,被多个权重复用
input = sram_input[ic][h][w];
output[oc][h][w] += input * weight;
}
}
}
}
你看,这里权重和输入都在SRAM里,被反复读取。如果每次计算都去HBM里取数据,那性能会惨不忍睹。
关键指标: 数据复用率 = 总计算次数 / 总数据搬运次数。这个值越高,说明你的存储层次设计得越好。
4.5 存储层次设计的“黄金法则”
做了这么多年芯片,我总结了几条经验:
- 法则一: 把最频繁访问的数据放在离计算单元最近的地方。比如权重,如果能全放在SRAM里,就别去HBM里取。
- 法则二: 用“乒乓缓冲”隐藏数据搬运延迟。一块SRAM在计算,另一块在预取数据,交替进行。
- 法则三: 别让存储成为瓶颈。计算单元再快,数据喂不饱也是白搭。我习惯在设计初期就做“带宽预算”——算清楚每个模块需要多少带宽,然后反推存储层次。
一个小技巧: 设计SRAM时,考虑“多bank”结构。把SRAM分成多个独立的bank,可以同时访问,提高带宽。我有个项目,把SRAM从单bank改成4bank,性能提升了30%。
4.6 知识体系图:存储层次的核心逻辑
下面这张图,是我自己画的。它展示了AI芯片存储层次的核心逻辑:从片外到片上,从慢到快,从大到小。数据在层次间流动,复用策略决定了流动的效率。
这张图里,从上到下是数据流动的方向。片外存储是“水源”,片上存储是“水库”,计算单元是“用水户”。数据复用策略,就是决定“水”怎么分配、怎么循环利用的调度方案。
嗯,说到这儿,我想起一个项目。当时我们设计了一款边缘AI芯片,片内SRAM只有2MB。为了跑一个MobileNet,我们花了整整两周优化数据复用策略。最后把片外访问次数降到了原来的1/5,性能翻了一倍。所以说,存储层次设计,真的是一门“螺蛳壳里做道场”的功夫。
总结一下: 存储层次设计的本质,就是用有限的片上资源,最大化数据复用,最小化片外访问。记住三个关键词:层次化、复用、带宽匹配。
想要更多资料,联系可可