第三章 计算单元设计:从MAC到脉动阵列
大家好,我是老张。今天咱们聊聊AI加速器里最核心的东西——计算单元。
说实话,很多新手一上来就盯着架构图看,觉得脉动阵列很神秘。其实没那么玄乎。咱们从最基础的乘累加器开始,一步步往上搭。
3.1 乘累加器(MAC)微架构
MAC是啥?说白了就是一个乘法器加一个加法器。但你别小看它,AI芯片里90%的计算量都靠它。
核心公式:D = A × B + C
我刚开始做设计时,总觉得MAC很简单。直到有一次做低功耗优化,才发现里面门道多着呢。
3.1.1 基本结构
一个典型的MAC单元包含:
- 乘法器:处理A×B
- 加法器:累加结果
- 累加寄存器:存储中间结果
嗯,这里要注意:累加寄存器的位宽一定要够。我曾经吃过这个亏——16位乘法结果累加32次,寄存器溢出,整个模型推理全错。
避坑指南:累加器位宽 = 乘法结果位宽 + log2(累加次数)。别省这点面积,否则流片回来哭都来不及。
3.1.2 流水线设计
为什么MAC要搞流水线?你想想看,乘法器延迟大,加法器延迟小。如果串行做,时钟频率上不去。
我习惯把MAC分成三级流水:
- 第一级:乘法运算
- 第二级:加法运算
- 第三级:结果写回
// 三级流水MAC的Verilog描述
always @(posedge clk) begin
if (rst) begin
mul_result <= 0;
add_result <= 0;
acc_result <= 0;
end else begin
// Stage 1: 乘法
mul_result <= a * b;
// Stage 2: 加法
add_result <= mul_result + c;
// Stage 3: 累加
acc_result <= add_result + acc_result;
end
end
小技巧:如果面积允许,可以给每个MAC配两个累加寄存器。一个做当前计算,一个做数据搬运。这样能隐藏数据搬移延迟。
3.2 脉动阵列(Systolic Array)原理
单个MAC算力有限。怎么把一堆MAC组织起来?脉动阵列就是答案。
我记得第一次看到脉动阵列的论文时,觉得这玩意儿太巧妙了。数据像血液一样在阵列里流动,每个MAC只做最简单的事——乘加、传递。
3.2.1 工作原理
脉动阵列的核心思想:
- 数据从左边流进来(权重)
- 数据从上面流进来(输入特征)
- 结果从下面流出去(部分和)
说白了,就是让数据动起来,计算单元不动。这样能最大化数据复用。
关键点:每个MAC只和邻居通信。没有全局连线,时序好做,频率能跑高。
3.2.2 矩阵乘法映射
假设我们要做C = A × B。A是M×K,B是K×N。
映射方式:
- 把A矩阵的每一行广播到阵列的行
- 把B矩阵的每一列广播到阵列的列
- 每个MAC计算一个点积
我做过一个16×16的脉动阵列,跑ResNet-50,利用率能到85%以上。但要注意,矩阵尺寸不是16的倍数时,会有浪费。
我曾经踩过的坑:脉动阵列的边界处理。如果矩阵尺寸不是阵列尺寸的整数倍,需要补零。但补零会浪费计算周期。后来我改用动态调度,根据实际矩阵大小调整数据流。
3.3 向量处理单元(VPU)设计
脉动阵列擅长矩阵乘法,但AI里还有不少向量操作——激活函数、归一化、池化。这些就得靠VPU了。
3.3.1 VPU架构
一个典型的VPU包含:
- 向量寄存器文件:存储向量数据
- 向量ALU:支持加、减、乘、比较等
- 向量加载/存储单元:从内存搬数据
我个人习惯把VPU设计成可配置的。比如向量长度可以配成64、128、256。这样能适配不同精度的模型。
3.3.2 指令集设计
VPU的指令集要简洁。我见过有些设计搞了几百条指令,结果编译器根本用不上。
常用的向量指令:
VADD vd, vs1, vs2 // 向量加法
VMUL vd, vs1, vs2 // 向量乘法
VRELU vd, vs // 向量ReLU
VMAX vd, vs1, vs2 // 向量最大值
经验之谈:VPU的指令编码要留扩展位。我第一版设计没留,后来想加个向量乘加指令,结果指令格式全得改。血的教训。
3.4 SIMD与SIMT架构对比
这两个概念经常被混淆。我简单说说区别。
| 特性 | SIMD | SIMT |
|---|---|---|
| 控制单元 | 单个控制单元 | 多个控制单元(每个线程一个) |
| 数据路径 | 宽数据路径(128/256/512位) | 多个窄数据路径 |
| 分支处理 | 需要显式掩码 | 硬件自动处理 |
| 编程模型 | 向量化编程 | 线程级编程 |
| 典型代表 | ARM NEON, x86 AVX | NVIDIA CUDA |
你想想看,SIMD就像一条流水线上有多个工人,每个人干不同的活。SIMT就像多条流水线,每条线上一个工人干自己的活。
我做过一个对比实验:同样的卷积操作,SIMD实现比SIMT快15%,但编程复杂度高很多。SIMT虽然慢一点,但程序员写起来舒服。
我的建议:如果是做专用AI芯片,用SIMD更合适。如果是做通用GPU,SIMT更灵活。没有绝对的好坏,看应用场景。
3.5 本章知识体系
下面这张图展示了本章的核心逻辑:
从这张图能看出来,MAC是基础,脉动阵列和VPU是两种不同的扩展方向。SIMD和SIMT则是更高层次的架构选择。
最后说一句:设计计算单元时,别光盯着峰值算力。实际能跑出来的算力才是真本事。我见过太多芯片,理论算力100TOPS,实际跑模型只有30TOPS。问题就出在数据搬运和利用率上。
公众号:蓝海资料掘金营,微信deep3321