3. 收发器与卷积的映射:为什么用收发器加速卷积

好,咱们直接切入正题。收发器这玩意儿,说白了就是高速串行接口。你可能会问,我做个卷积加速器,跟高速串口有什么关系?

嗯,这个问题我当年也困惑过。直到我在一个项目中,需要把大量数据从外部存储器搬到FPGA内部做卷积运算。那时候用的还是传统的并行总线,结果呢?带宽不够,数据搬不过来,卷积核在那干等着。那叫一个憋屈。

后来我换了个思路——用收发器。效果立竿见影。

3.1 为什么用收发器加速卷积

核心原因就一个:带宽瓶颈。

卷积运算的本质是什么?是乘累加。一个3x3的卷积核,每次需要9个像素数据。如果数据从外部进来,带宽跟不上,那你的乘法器再多也没用。

收发器能提供什么?

  • 单通道速率高:一个12.5Gbps的收发器通道,相当于1.5GB/s的带宽
  • 多通道并行:一个FPGA里几十个收发器通道,总带宽轻松上百GB/s
  • 延迟低:SerDes结构,数据进来直接串转并,不用经过复杂的总线协议

一句话总结:收发器解决了卷积加速器的"喂数据"问题。没有它,你的加速器就是个饿着肚子的壮汉,有力使不出。

我记得有一次做视频处理,输入是4K@60fps的流。如果用传统DDR+并行总线的方式,光数据搬运就占了70%的逻辑资源。换成收发器直连之后,资源占用降到20%以下。差距就是这么明显。

3.2 数据流与并行度分析

好,现在我们知道收发器能提供高带宽。但怎么用?这就涉及到数据流和并行度的设计了。

先看数据流。卷积加速器里,数据流动主要有三种模式:

  1. 行流模式:数据按行输入,一行一行地进。适合做行缓冲
  2. 块流模式:数据按图像块输入,比如8x8的块。适合做窗口滑动
  3. 通道流模式:多通道数据同时输入。适合做多特征图并行

收发器最适合的是通道流模式。为什么?因为每个收发器通道都是独立的,你可以把不同的特征图分配到不同的通道上。

举个例子。假设你有一个卷积层,输入是64个特征图,每个特征图是224x224。如果用传统方式,你得先把64个特征图串行化,再一个一个处理。但用收发器呢?

  • 用8个收发器通道,每个通道处理8个特征图
  • 每个通道内部,数据以流水线方式处理
  • 8个通道并行工作,吞吐量直接翻8倍

我的经验:并行度不是越高越好。收发器通道数多了,PCB布线会变得非常复杂。我一般建议控制在8-16个通道之间,性价比最高。

再说并行度。卷积的并行度可以从三个维度看:

维度 说明 收发器优势
输入通道并行 多个输入特征图同时处理 每个通道独立传输,天然支持
输出通道并行 多个卷积核同时计算 需要内部做数据分发,收发器只负责输入
空间并行 同一特征图的不同位置同时计算 需要配合行缓冲,收发器提供数据源

我个人习惯是:优先做输入通道并行。因为收发器最擅长这个,不需要额外逻辑。输出通道并行和空间并行,交给FPGA内部的逻辑资源去处理。

3.3 收发器通道与卷积核的对应关系

这是最核心的部分。收发器通道和卷积核怎么对应?

先看一个简单的映射关系图:

收发器通道与卷积核映射关系 收发器 通道组 通道0 通道1 通道2 通道3 数据 分发网络 → 特征图0 → 特征图1 → 特征图2 → 特征图3 卷积核组 卷积核0 (3x3x64) 处理特征图0 卷积核1 (3x3x64) 处理特征图1 卷积核2 (3x3x64) 处理特征图2 卷积核3 (3x3x64) 处理特征图3

从图上可以看得很清楚:

  • 每个收发器通道对应一个输入特征图
  • 每个输入特征图对应一组卷积核
  • 数据分发网络负责把通道数据路由到对应的卷积核

这里有个关键点:收发器通道和卷积核不是一一对应的。一个通道的数据,可能会被多个卷积核共享。比如在YOLO网络中,同一个输入特征图会被多个卷积核处理。

注意:我曾经犯过一个错误——把收发器通道直接映射到卷积核上,结果发现数据冲突了。后来才明白,收发器只管搬数据,卷积核只管算数据,中间需要一层数据分发逻辑来做路由。

具体怎么映射?我一般用这个公式:

// 收发器通道与卷积核的映射关系
// 假设:
//   N_ch = 收发器通道数
//   K_in = 输入特征图数
//   K_out = 输出特征图数

// 每个通道负责的特征图数
feature_maps_per_channel = K_in / N_ch

// 每个特征图对应的卷积核数
kernels_per_feature_map = K_out

// 总计算量
total_ops = N_ch * feature_maps_per_channel * kernels_per_feature_map * kernel_size^2

举个例子。假设你有4个收发器通道,输入是16个特征图,输出是32个特征图:

  • 每个通道负责4个特征图(16/4=4)
  • 每个特征图对应32个卷积核
  • 每个通道需要处理4x32=128个卷积核的计算

这样设计的好处是:数据流清晰,并行度高,而且容易扩展。想提高性能?加收发器通道就行。

避坑指南:我曾经在一个项目里,把收发器通道数设得太多,结果PCB上走线都走不开。后来学乖了,先做可行性分析,再定通道数。一般建议:通道数不要超过FPGA封装能支持的差分对数量的一半。

最后说一句。收发器加速卷积,本质上是用硬件带宽换计算速度。你想想看,如果没有收发器,数据从DDR过来,经过AXI总线,再进到卷积核,延迟大、带宽低。有了收发器,数据直接飞进来,延迟降到纳秒级,带宽翻几倍。这笔账,怎么算都划算。

嗯,这一章就到这里。下一章我们会聊收发器的具体配置和调试方法,到时候我会分享一些实战中的踩坑经验。