3. 数据流核心概念:时间数据流与空间数据流的定义与区别
好,咱们进入正题。这一节要聊的,是整个Eyeriss数据流映射里最基础、也最容易搞混的两个概念——时间数据流和空间数据流。
我刚开始接触数据流映射时,也在这上面栽过跟头。当时看,满篇的“temporal”和“spatial”,觉得不就是时间跟空间嘛,有啥难理解的?结果一动手做映射,发现根本不是那么回事。你想想看,一个数据在同一个时钟周期里被多个PE用了,这算时间还是空间?一个数据在不同时钟周期被同一个PE反复用,这又算什么?
嗯,别急。咱们先把定义掰扯清楚。
3.1 时间数据流:数据在时间维度上的复用
时间数据流,说白了就是同一个数据,在不同时间点被同一个处理单元(PE)重复使用。数据在时间轴上“流动”,PE在多个时钟周期里反复读取它。
举个例子,你在做卷积时,一个输入像素要被同一个卷积核反复乘很多次。如果这个像素被加载到PE的寄存器里,然后PE在每个时钟周期都拿它跟不同的权重做乘加——这就是典型的时间数据流。
核心特征:
- 数据在同一个PE内部被多次使用
- 使用发生在不同的时钟周期
- 依赖PE内部的存储(寄存器、局部缓存)来保持数据
- 减少对全局存储的访问带宽需求
我在做第一版Eyeriss原型时,就吃过时间数据流的亏。当时为了省带宽,我把输入特征图的数据在PE里反复用了32次,结果发现PE内部的寄存器堆根本不够用,数据被挤到局部SRAM里,延迟一下子飙了上去。后来我学乖了——时间复用不是越多越好,得看PE的本地存储能装下多少。
3.2 空间数据流:数据在空间维度上的广播
空间数据流,则是同一个数据,在同一个时间点被多个不同的处理单元(PE)同时使用。数据在空间上“广播”,多个PE在同一时钟周期里拿到相同的数据。
还是拿卷积举例。一个输入像素,如果同时被送到多个PE里,每个PE拿它跟不同的权重做乘加——这就是空间数据流。说白了,就是“一份数据,多份拷贝,同时计算”。
核心特征:
- 数据在多个PE之间被同时使用
- 使用发生在同一个时钟周期
- 依赖数据分发网络(广播总线、多播网络)来传递数据
- 减少对PE本地存储的容量需求
空间数据流的好处是延迟低——数据一到,所有PE立刻开算。但代价也很明显:你得有足够宽的数据分发总线,否则广播会成为瓶颈。我记得有一次做仿真,空间复用因子设到16,结果总线拥堵导致PE有一半时间在空等。嗯,那感觉就像高速公路上所有车都挤在同一个出口下。
3.3 两者的本质区别
咱们用一张表把区别说清楚:
| 对比维度 | 时间数据流 | 空间数据流 |
|---|---|---|
| 复用对象 | 同一个PE | 多个PE |
| 复用时刻 | 不同时钟周期 | 同一时钟周期 |
| 存储依赖 | PE本地存储(寄存器/缓存) | 数据分发网络(总线/多播) |
| 带宽影响 | 降低全局带宽需求 | 增加分发网络带宽需求 |
| 延迟特征 | 较高(数据需多次读取) | 较低(数据一次到位) |
| 典型场景 | 权重在PE内复用 | 输入特征图广播到多个PE |
你可能会问:那到底哪个更好?
我的回答是:没有哪个更好,只有哪个更合适。Eyeriss的精髓,恰恰在于把时间数据流和空间数据流混合使用,取长补短。
3.4 混合数据流:Eyeriss的核心思路
Eyeriss不是单纯用时间或空间数据流,而是把两者结合起来。具体来说:
- 行间(Row-wise):输入特征图的行数据在PE阵列里做空间广播,同一行数据同时送到多个PE
- 行内(Within-row):同一行内的权重在PE内部做时间复用,一个PE反复使用同一组权重
这样做的好处很明显:
- 空间广播减少了PE本地存储的压力——你不用在每个PE里都存一份完整的输入特征图
- 时间复用降低了全局带宽——权重在PE内部反复用,不用频繁从全局缓存搬数据
- 两者配合,让存储层次和计算单元都能高效运转
我的经验: 在做数据流映射时,我习惯先确定瓶颈在哪。如果带宽是瓶颈,就多用时间复用;如果PE本地存储是瓶颈,就多用空间广播。Eyeriss的混合数据流,本质上就是在带宽和存储之间找一个平衡点。
3.5 一张图看懂时间 vs 空间数据流
下面这张SVG图,把时间数据流和空间数据流的区别画得清清楚楚:
注意: 千万别把时间数据流和空间数据流割裂开来看。实际芯片里,两者是同时存在的。一个数据可能在同一个时钟周期被多个PE用(空间),然后在接下来的几个周期里又被同一个PE反复用(时间)。你设计数据流映射时,得同时考虑这两个维度。
3.6 避坑指南:我踩过的几个坑
最后,分享几个我实际项目中遇到的坑,希望能帮你少走弯路:
- 坑一:过度追求时间复用。我曾经在一个项目里,把权重在PE内复用了64次,结果PE的寄存器堆爆了,数据不得不频繁换入换出,延迟反而比不复用还高。记住:时间复用的上限,由PE本地存储容量决定。
- 坑二:忽视空间广播的功耗。空间数据流虽然延迟低,但广播网络的功耗不容小觑。数据每多广播到一个PE,总线上就要多驱动一个负载。我见过一个设计,空间复用因子从4提到8,功耗直接翻了1.7倍。
- 坑三:混淆“时间”和“空间”的边界。有些数据流,数据在PE阵列里逐级传递(比如脉动阵列),每个PE在不同时间点拿到数据。这算时间还是空间?严格来说,这是时间数据流,因为数据在不同时间点被不同PE使用。别被“多个PE”这个表象骗了。