4. 数据流架构:权值固定流、输出固定流、输入固定流三种主流数据流分析
做卷积加速器这么多年,我见过不少团队在数据流选择上栽跟头。说白了,数据流就是决定数据怎么在计算阵列里流动、怎么复用、怎么存储。选错了,带宽翻倍、面积爆炸,流片回来性能对不上预期——这种事我遇到过不止一次。
今天咱们把三种主流数据流掰开揉碎讲清楚。权值固定流、输出固定流、输入固定流,你想想看,它们本质上是在解决同一个问题:如何最大化数据复用,最小化片外访存。
4.1 权值固定流(Weight Stationary)
权值固定流,顾名思义,就是让权重数据待在原地不动。计算阵列里的每个PE(处理单元)把权值加载进来之后,就一直存着,直到所有需要这个权值的输入都算完。
我个人习惯把这种架构叫做“守株待兔”模式。权值像钉子一样钉在PE里,输入数据流过来,跟权值做乘加,然后输出流出去。
核心特点:
- 权值只在开始时加载一次,后续完全复用
- 输入数据需要广播到所有PE
- 部分和(partial sum)需要在PE间传递
我在一个边缘端AI芯片项目里用过这种架构。当时卷积核是3x3,权值复用率很高,片内SRAM放得下所有权值。效果不错,功耗控制得很好。
优点:
- 权值访存次数最少,适合权值大的场景
- PE内部寄存器利用率高
- 控制逻辑相对简单
缺点:
- 输入数据需要频繁广播,总线压力大
- 部分和累加路径长,可能成为时序瓶颈
- 对输入特征图尺寸变化不灵活
避坑指南:我曾经在一个项目中,权值固定流做得太死,结果输入特征图尺寸一变,广播路径的扇出太大,时序直接崩了。后来加了输入缓冲和树形广播结构才解决。建议你设计时留好余量。
4.2 输出固定流(Output Stationary)
输出固定流是另一种思路。每个PE负责计算输出特征图上的一个固定位置,输入数据和权值都流进来,算完就输出,PE本身不存任何中间结果。
说白了,这就是“各扫门前雪”。每个PE只盯着自己那一个输出像素,谁来跟它算就跟谁算。
核心特点:
- 输出结果在PE本地累加,完成后一次性写出
- 输入数据和权值都需要在PE间传递
- 部分和不需要在PE间传递
嗯,这里要注意:输出固定流对部分和的累加非常友好。因为每个PE只算一个输出点,所有乘加结果都在本地累加,不需要额外的加法树。
优点:
- 部分和累加路径最短,时序容易收敛
- 输出数据写回次数少
- 适合输出通道数多的场景
缺点:
- 权值和输入都需要在PE间传递,数据路径复杂
- PE利用率可能受限于数据供应速度
- 权值复用率不如权值固定流
| 数据流类型 | 权值复用 | 输入复用 | 部分和传递 | 典型应用 |
|---|---|---|---|---|
| 权值固定流 | 高 | 低 | 需要 | 权值大的卷积层 |
| 输出固定流 | 中 | 中 | 不需要 | 输出通道多的层 |
| 输入固定流 | 低 | 高 | 需要 | 输入特征图大的层 |
4.3 输入固定流(Input Stationary)
输入固定流,就是把输入数据固定在PE里。权值和输出结果流进来流出去。这种架构适合输入特征图特别大的场景,比如第一层卷积,输入是高清图片。
我记得有个做视频处理的客户,输入是1080p的帧,用输入固定流效果就很好。输入数据在PE里待着不动,权值轮流转进来,算完一个输入点再换下一个。
核心特点:
- 输入数据只在开始时加载一次
- 权值需要在PE间广播或传递
- 部分和需要在PE间累加
优点:
- 输入数据复用率最高,适合大输入
- 输入带宽压力小
- 对输入数据流友好,容易做流水
缺点:
- 权值需要频繁加载,带宽开销大
- 部分和累加路径长
- 权值存储压力大
注意:输入固定流有个坑——权值加载次数太多。我曾经有个设计,权值加载占了总访存带宽的70%以上,导致整体性能上不去。后来改成混合数据流才解决。所以选型时一定要算清楚带宽账。
4.4 三种数据流的对比与选择
你可能会问:到底选哪种?其实没有银弹。我一般会从三个维度来评估:
- 数据复用率:哪个数据在计算中复用次数最多,就把它固定住
- 存储层次:片内SRAM能放下什么,什么就适合做固定流
- 带宽瓶颈:哪个数据的带宽最紧张,就优先减少它的访存
举个例子,如果卷积层权值很大(比如全连接层),权值固定流就是首选。如果输入特征图很大(比如第一层),输入固定流更合适。如果输出通道很多,输出固定流能减少部分和累加的开销。
下面这张图展示了三种数据流在计算阵列中的流动方式:
4.5 混合数据流:实际工程中的选择
说实话,在实际芯片里,很少有人只用一种纯数据流。我参与过的几个量产项目,基本都是混合的。比如:
- 前几层用输入固定流(输入大)
- 中间层用权值固定流(权值复用高)
- 最后几层用输出固定流(输出通道多)
甚至可以在同一个卷积层里,不同维度用不同数据流。比如行方向用权值固定,列方向用输出固定。这种设计灵活性高,但控制逻辑也复杂得多。
我的建议:刚开始做设计时,先选一种主流数据流把原型跑通。等性能瓶颈暴露出来,再针对性地加混合策略。别一开始就搞得太复杂,容易翻车。
最后说一句:数据流的选择没有标准答案。它取决于你的应用场景、带宽预算、面积约束和功耗目标。多仿真、多对比,找到最适合你的那一种。