数据流与脉动阵列:脉动阵列原理、权重固定流、输入固定流、输出固定流

好,咱们今天聊点硬核的——脉动阵列。说实话,我第一次接触这个概念是在读研的时候,当时看论文里那些规规整整的格子图,觉得这东西不就是个二维数组嘛,有啥了不起的?直到后来我在一家AI芯片公司做编译器,真正去写调度策略的时候,才发现这玩意儿的水深得很。

脉动阵列,说白了就是一种数据流驱动的计算结构。它的核心思想是:让数据像心跳一样,有节奏地在处理单元(PE)之间流动。每个PE只做简单的乘加运算,但通过巧妙的连接方式,整个阵列能高效完成矩阵乘法这类计算。

核心要点:脉动阵列的三大优势——高吞吐、低访存、规整性好。但代价是控制逻辑复杂,数据流调度需要精心设计。

脉动阵列的基本原理

想象一下,你有一排工人(PE),每个人手里拿着一个计算器。原材料(输入数据)从左边传进来,每个人做完自己的计算后,把结果传给右边的人。这就是一维脉动阵列的雏形。

二维的情况更常见。比如一个8x8的PE阵列,数据从上方和左侧流入,计算结果从右侧和下方流出。每个PE内部有一个乘加器(MAC)和少量寄存器。嗯,这里要注意:PE内部的寄存器大小直接决定了你能处理多大的数据块。

我习惯把脉动阵列的工作方式分成三种:权重固定流、输入固定流和输出固定流。这三种方式对应着不同的数据复用策略,也直接影响着编译器的调度难度。

脉动阵列三种数据流模式对比 权重固定流 权重预加载 输入从左到右流动 部分和从上到下累加 输入固定流 输入预加载到PE 权重从上到下流动 部分和在PE内累加 输出固定流 部分和预加载到PE 输入和权重同时流动 结果在PE内累加

权重固定流(Weight Stationary)

这种方式,说白了就是把权重(也就是卷积核的参数)提前加载到PE里,然后让输入数据在阵列中流动。每个PE拿着自己的权重,跟流经的输入数据做乘加。

我在项目中遇到过这样一个场景:做图像分类网络时,卷积核参数是固定的,但输入特征图很大。这时候用权重固定流就特别合适——权重只加载一次,输入数据流过来,每个PE重复使用自己的权重。你想想看,这能省多少带宽?

我的经验:权重固定流最适合权重复用度高的场景。比如卷积层,同一个卷积核要在输入特征图上滑动很多次。我曾经在一个边缘AI芯片上,用这种方式把DDR带宽降低了60%。

但要注意一个问题:权重固定流要求PE内部有足够的寄存器来存储权重。如果卷积核太大(比如7x7),PE的寄存器可能装不下。这时候就需要做权重分片,嗯,调度起来就麻烦多了。

输入固定流(Input Stationary)

输入固定流正好反过来。输入数据被预加载到PE里,权重在阵列中流动。每个PE拿着自己的输入数据,跟流经的权重做乘加。

为什么会有人用这种方式?我举个例子:在做全连接层时,输入是固定的特征向量,但权重矩阵很大。这时候把输入固定在PE里,让权重流过来,每个PE只需要存一份输入数据,权重可以分批加载。

数据流模式 数据复用对象 适合场景 PE寄存器需求
权重固定流 权重 卷积层(权重复用度高) 大(存权重)
输入固定流 输入 全连接层(输入复用度高) 中(存输入)
输出固定流 部分和 深度可分离卷积 小(存累加结果)

避坑指南:我曾经在一个项目中,想当然地用了输入固定流来处理卷积层。结果发现输入特征图太大,每个PE要存的数据量远超寄存器容量,导致频繁的DMA搬运,性能反而下降了。后来改成权重固定流,问题才解决。

输出固定流(Output Stationary)

输出固定流,说白了就是把部分和(partial sum)固定在PE里。输入和权重同时流动,每个PE负责累加自己对应的输出像素。

这种方式在深度可分离卷积中特别有用。你想想看,深度可分离卷积先做逐通道卷积,再做逐点卷积。在逐通道卷积阶段,每个输出通道只跟一个输入通道相关,用输出固定流正好可以把每个通道的部分和累加在一起。

我个人习惯在做编译器调度时,优先考虑输出固定流。为什么?因为它的数据依赖关系最清晰。每个PE只关心自己的输出,不需要跟邻居交换数据。但代价是输入和权重都要流动,对片上网络的带宽要求更高。

如何选择数据流模式?

这个问题没有标准答案。我一般会从三个维度来考虑:

  • 数据复用度:哪个数据被重复使用的次数最多,就把它固定下来
  • PE寄存器容量:寄存器够大就固定数据,不够大就让数据流动
  • 片上网络带宽:带宽够用就多流动,带宽紧张就多固定

举个例子,假设你有一个3x3的卷积核,输入特征图是64x64。权重复用度是64x64=4096次,输入复用度是9次(每个输入像素被9个权重用到)。很明显,权重复用度更高,所以权重固定流更合适。

核心结论:没有最好的数据流模式,只有最合适的。编译器工程师的职责就是根据硬件特性和算子特点,动态选择最优的数据流方案。

好了,关于脉动阵列的三种数据流模式,我就讲到这里。记住一点:数据流模式的选择,本质上是在计算效率和数据搬运开销之间做权衡。你想想看,是不是这个道理?

想要更多资料,联系可可