第二章:AI芯片架构基础

做AI芯片性能建模这些年,我最大的感触是:不懂硬件架构,性能建模就是空中楼阁。你想想看,连芯片怎么算、数据怎么存、数据怎么流都不清楚,那模型再漂亮也是白搭。

这一章,咱们就聊聊AI芯片最核心的三个基础模块:计算单元存储层次数据流。嗯,这三个东西搞明白了,后面讲性能建模你就知道我在说什么了。

核心观点:AI芯片的性能瓶颈,90%不在计算,而在数据搬运。记住这句话,后面你会反复体会到。

AI芯片架构基础:三大核心模块 计算单元 MAC · SIMD · Vector 存储层次 SRAM · HBM · DDR 数据流 WS · IS · OS 乘加运算 · 并行处理 · 向量化 片上缓存 · 高带宽 · 大容量 权重固定 · 输入固定 · 输出固定 三者关系 计算单元决定算力上限 → 存储层次决定数据供给 → 数据流决定效率 性能建模 = 算力 × 带宽利用率 × 数据流效率

2.1 计算单元:芯片的「肌肉」

计算单元说白了就是芯片干活的家伙。AI计算最核心的操作是什么?乘加运算。一个卷积层,就是成千上万个乘加操作堆出来的。

2.1.1 MAC(乘加运算单元)

MAC就是做一次乘法和一次加法。比如 y = w × x + b,这就是一个MAC操作。AI芯片里通常有成千上万个MAC单元并行工作。

我个人习惯把MAC阵列想象成「算力工厂」——每个MAC是一个工人,工人越多,工厂产能越高。但注意,工人多了,原材料(数据)供应也得跟上,不然工人就闲着。

避坑指南:我曾经在建模时只关注MAC数量,忽略了数据供给。结果模型预测的算力是100 TOPS,实际跑起来只有40 TOPS。原因?数据搬运不过来,MAC在空转。嗯,从那以后我建模必加「带宽利用率」这个参数。

2.1.2 SIMD(单指令多数据)

SIMD就是一条指令同时处理多个数据。举个例子,你要给100个数都加1,用SIMD一条指令就搞定了,不用写100条加法指令。

你想想看,这对AI计算多重要?卷积核在特征图上滑动,每个位置做的操作一模一样,只是数据不同。SIMD天然适合这种场景。

// 伪代码:SIMD vs 标量
// 标量方式
for (int i = 0; i < 16; i++) {
    C[i] = A[i] + B[i];  // 16条加法指令
}

// SIMD方式
vec_add(C, A, B, 16);    // 1条SIMD指令,同时处理16个数据

2.1.3 Vector(向量单元)

向量单元是SIMD的升级版。SIMD通常处理短向量(比如4个、8个数据),向量单元可以处理更长的向量(比如128个、256个数据)。

我记得在某个项目里,我们用向量单元做矩阵乘法,把矩阵拆成向量,一次处理一整行。性能直接翻了4倍。为什么?因为向量化减少了指令开销,也更好地利用了数据局部性。

关键指标:计算单元的利用率 = 实际完成的MAC数 / (峰值MAC数 × 时间)。理想情况是100%,但实际能到60%-80%就算不错了。

2.2 存储层次:芯片的「粮仓」

计算单元再强,数据供不上也是白搭。存储层次就是解决「数据从哪里来、到哪里去」的问题。

2.2.1 SRAM(片上缓存)

SRAM是离计算单元最近的存储,速度最快,但容量小、成本高。AI芯片里通常有几MB到几十MB的SRAM,用作缓存。

我个人习惯把SRAM比作「厨房操作台」——厨师(计算单元)需要什么材料,得提前摆在台面上。如果每次都要去仓库(DDR)拿,那效率就太低了。

存储类型 典型容量 带宽 延迟 功耗/bit
SRAM(片上) 1-64 MB 10-100 TB/s 1-5 ns ~0.1 pJ
HBM(高带宽内存) 4-32 GB 1-3 TB/s 50-100 ns ~2 pJ
DDR(双倍数据率内存) 8-128 GB 50-200 GB/s 100-200 ns ~5 pJ

看到这个表了吗?SRAM的功耗比DDR低了两个数量级。所以AI芯片设计的一个核心原则就是:尽量把数据留在SRAM里,少去访问DDR

2.2.2 HBM(高带宽内存)

HBM是3D堆叠的内存,通过硅通孔(TSV)和芯片直连。带宽极高,但容量和成本介于SRAM和DDR之间。

我曾经在评估一个推理芯片时,发现它的HBM带宽标称是2 TB/s,但实际有效带宽只有1.2 TB/s。为什么?因为HBM的访问模式有要求——连续访问效率高,随机访问效率低。建模时如果不考虑这个,性能预测就会偏乐观。

注意:HBM的带宽是共享的。如果多个计算单元同时访问HBM,就会产生竞争,实际带宽会下降。这个在性能建模里一定要考虑「带宽竞争因子」。

2.2.3 DDR(双倍数据率内存)

DDR是传统的内存,容量大、成本低,但带宽和延迟都不如HBM。在边缘端或低功耗场景,DDR还是主流。

嗯,这里要注意:DDR的带宽利用率受「行激活」和「列访问」的影响很大。连续访问同一行,带宽利用率高;频繁换行,利用率就低。我见过一个项目,因为数据布局不合理,DDR带宽利用率只有30%。

2.3 数据流:芯片的「调度策略」

数据流决定了数据怎么在计算单元和存储之间流动。不同的数据流策略,对性能的影响天差地别。

2.3.1 Weight Stationary(权重固定)

WS策略:把权重(卷积核)固定在计算单元里,输入数据流过来,权重不动。适合权重复用度高、输入数据变化快的场景。

举个例子,做图像分类时,一张图片要经过多个卷积层。如果权重固定,每层只需要加载一次权重,然后不断输入特征图就行。我习惯在推理场景用WS,因为权重是固定的,可以提前加载好。

// WS数据流示意
for each input_channel:
    for each output_channel:
        load weight[oc][ic] to MAC  // 权重固定
        for each input_row:
            for each input_col:
                load input[ic][row][col]
                MAC(weight, input)  // 输入流动,权重不动

2.3.2 Input Stationary(输入固定)

IS策略:把输入数据固定在计算单元里,权重流过来。适合输入数据复用度高、权重变化快的场景。

你想想看,什么时候输入复用度高?比如做批量推理时,同一张输入图片要跟多个卷积核做卷积。这时候把输入固定,权重轮流过来,效率就很高。

个人经验:我在做训练芯片建模时,发现IS策略在反向传播阶段特别有用。因为反向传播时,梯度数据复用度高,用IS可以减少梯度数据的搬运次数。

2.3.3 Output Stationary(输出固定)

OS策略:把部分和(partial sum)固定在计算单元里,权重和输入都流过来。适合输出特征图尺寸大、需要累加的场景。

OS策略的好处是减少了部分和的读写次数。我记得在某个项目里,用OS策略把部分和的搬运量减少了70%。但代价是控制逻辑更复杂,需要管理多个部分和的累加。

数据流策略 固定对象 适合场景 主要优势 主要劣势
Weight Stationary 权重 推理、权重复用高 权重搬运少 输入数据可能重复搬运
Input Stationary 输入 训练、批量推理 输入复用高 权重搬运频繁
Output Stationary 部分和 大输出特征图 减少部分和读写 控制逻辑复杂

2.4 三者如何协同?

计算单元、存储层次、数据流不是孤立的。它们必须协同工作,才能发挥芯片的最大性能。

我总结了一个简单的公式:

实际性能 = 峰值算力 × 存储带宽利用率 × 数据流效率

峰值算力由MAC数量和频率决定。存储带宽利用率取决于数据布局和访问模式。数据流效率取决于你选的策略是否匹配算法特点。

核心思想:性能建模不是算峰值,而是算「有效性能」。有效性能 = 峰值 × 利用率。而利用率,就是由存储层次和数据流共同决定的。

举个例子,一个芯片峰值算力100 TOPS,但存储带宽只有200 GB/s。如果数据流效率是50%,那实际性能可能只有40 TOPS。嗯,这就是为什么我说「数据搬运是瓶颈」。

好了,这一章的内容就到这里。记住这三个基础模块,后面讲性能建模方法时,你会反复用到它们。


公众号:蓝海资料掘金营,微信deep3321