计算单元设计基础:MAC阵列架构、乘加器微架构、数据流优化策略

好,咱们今天聊聊计算单元。这是深度学习加速器的心脏,说白了就是干活的“苦力”。你想想看,一个卷积层里几百万次乘加操作,全靠这玩意儿扛。我这些年做过的芯片里,计算单元的设计好坏,直接决定了芯片能效和性能的天花板。

MAC阵列架构:从单兵作战到集团冲锋

单个乘加器(MAC)就像一个小兵,能干但效率低。真正要跑大模型,得把成千上万个MAC组织起来,形成阵列。这就是MAC阵列的由来。

常见的阵列架构有几种:

  • 脉动阵列(Systolic Array):数据像血液一样在阵列里“流动”,每个MAC只跟邻居通信。优点是布局布线规整,功耗低。Google TPU就是典型代表。
  • 广播阵列(Broadcast Array):一个输入数据同时喂给所有MAC。优点是控制简单,但连线负载大,频率上不去。
  • 混合架构:结合两者优点,比如行广播、列脉动。我最近一个项目就用了这种,灵活性好不少。

我个人习惯,在做架构选型时,先看数据复用率。如果权重复用多,脉动阵列是首选。如果激活值复用多,广播阵列更合适。没有银弹,只有权衡。

核心要点:MAC阵列的规模(比如16x16、32x32)决定了算力上限。但规模越大,数据搬运的代价也越大。别光盯着TOPS,要看TOPS/W。

MAC阵列数据流示意图(脉动阵列) 输入特征图 权重 MAC MAC MAC MAC MAC MAC MAC MAC MAC 部分和输出 → 特征图数据流(行方向) ↓ 权重数据流(列方向) → 部分和输出(对角线方向)

乘加器微架构:细节决定成败

单个MAC怎么设计?这里门道可多了。最基本的乘加器就是乘法器+加法器。但深度学习里,数据位宽通常很窄(INT8、INT4),所以我们可以做很多优化。

我给大家看一个典型的INT8乘加器微架构:

// 简化的INT8乘加器RTL描述
module mac_int8 (
    input  clk,
    input  rst_n,
    input  [7:0] a,      // 激活值
    input  [7:0] w,      // 权重
    input  [31:0] psum_in, // 输入部分和
    output reg [31:0] psum_out // 输出部分和
);

    wire [15:0] product;
    wire [31:0] sum;

    // 乘法器:8bit x 8bit = 16bit
    assign product = a * w;

    // 加法器:16bit + 32bit = 32bit
    assign sum = psum_in + product;

    // 流水线寄存器
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n)
            psum_out <= 32'b0;
        else
            psum_out <= sum;
    end

endmodule

嗯,这里要注意。上面的代码只是教学用的简化版。实际项目中,乘法器会用Wallace树或Dadda树来优化面积和速度。加法器也会用进位保存加法器(CSA)来减少关键路径。

实战技巧:我曾经在一个项目里,为了省面积,把乘法器拆成了两个4bit乘法器再加起来。结果时序崩了。后来才意识到,对于高频设计,宁可多用点面积,也要保证乘法器是单周期的。面积换速度,值不值?看你目标频率。

数据流优化策略:让数据少跑路

数据流优化,说白了就是减少数据搬运。你想想看,从DRAM搬一次数据到片上SRAM,功耗是计算本身的几百倍。所以,优化的核心就是:尽量复用数据,减少访存

常见的优化策略有:

  1. 权重固定(Weight Stationary):权重加载后不动,激活值流进来。适合权重复用度高的场景,比如全连接层。
  2. 输出固定(Output Stationary):部分和留在本地,不断累加。适合输出通道多的场景。
  3. 行固定(Row Stationary):Eyeriss提出的经典策略,把卷积核的一行数据固定,减少数据搬运。我特别喜欢这个思路,它把数据复用做到了极致。

咱们用表格对比一下:

策略 数据复用方式 适用场景 优缺点
权重固定 权重不动,激活值流动 全连接层、权重复用高 控制简单,但激活值搬运多
输出固定 部分和不动,权重和激活值流动 输出通道多 减少部分和搬运,但控制复杂
行固定 卷积核行数据固定 卷积层 数据复用率高,但调度复杂

避坑指南:我曾经在一个项目里,想当然地用了权重固定策略,结果发现激活值数据量太大,片上SRAM根本存不下。后来改成行固定,配合数据压缩,才把带宽降下来。所以,选策略前,一定要先算清楚数据量。

最后,我想说一句。数据流优化没有标准答案,它跟你的芯片面积、功耗预算、目标应用强相关。我个人的习惯是,先做一轮数据流建模,把各种策略的访存次数算出来,再结合硬件资源做决策。别拍脑袋,要拍数据。

好了,这一章就到这里。记住,计算单元是加速器的“心脏”,而数据流是“血液”。心脏要强,血液要通,芯片才能跑得又快又省电。

专注资料整理