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计算中,数据复用主要有三种模式:

  1. 输入特征图复用(Input Reuse): 同一个输入特征图,被多个卷积核共享。比如一个3x3的卷积,输入数据会被9个权重复用。
  2. 权重复用(Weight Reuse): 同一个权重,被多个输出通道共享。这在全连接层里特别明显。
  3. 输出累加复用(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芯片存储层次与数据流 片外存储层 HBM / DDR(大容量,高延迟,低带宽) 片上存储层(SRAM) 全局缓存(几MB) → 共享缓存(几百KB) → 寄存器文件(几十KB) 延迟:几十个时钟周期 → 几个时钟周期 → 1-2个时钟周期 计算单元(MAC阵列 / 向量处理器) 数据复用策略:输入复用 / 权重复用 / 输出复用 核心目标:提高数据复用率,减少片外访问,突破存储墙 复用率 = 总计算次数 / 总数据搬运次数 速度越来越快 容量越来越小

这张图里,从上到下是数据流动的方向。片外存储是“水源”,片上存储是“水库”,计算单元是“用水户”。数据复用策略,就是决定“水”怎么分配、怎么循环利用的调度方案。

嗯,说到这儿,我想起一个项目。当时我们设计了一款边缘AI芯片,片内SRAM只有2MB。为了跑一个MobileNet,我们花了整整两周优化数据复用策略。最后把片外访问次数降到了原来的1/5,性能翻了一倍。所以说,存储层次设计,真的是一门“螺蛳壳里做道场”的功夫。

总结一下: 存储层次设计的本质,就是用有限的片上资源,最大化数据复用,最小化片外访问。记住三个关键词:层次化、复用、带宽匹配。

想要更多资料,联系可可