FPGA 可重构加速

FPGA 用可重构逻辑换取极致的能效与确定性延迟。本文讲清 LUT/DSP/BRAM 的硬件结构、HDL 与 HLS 两条开发路径、数据搬运与流水线设计、部分重配置、工具链生态、典型加速场景,以及 FPGA 与 CPU/GPU 协同的异构编程与选型权衡。

GPU 用成千上万个简单核心换吞吐,FPGA 走的是另一条路:用可重构的逻辑资源「现场烧出」一个专用电路。没有指令取指、没有缓存层级、没有调度开销,数据流过精心排布的运算单元,延迟以纳秒计且完全确定。这让 FPGA 在低延迟、高能效、非标准数据宽度的场景里独占鳌头——高频交易、基因组比对、网络包处理、实时信号处理。但代价是开发周期长、编程抽象低、峰值算力不及 GPU。本文讲清 FPGA 的硬件结构、两条开发路径与选型权衡。与 GPU 的通用优化方法可对照 GPU 内核性能优化 阅读。

为什么选择 FPGA

FPGA 的竞争力来自三个「反 GPU」的特性:

维度GPUFPGA
延迟微秒级(内核启动+访存)纳秒~微秒级,确定
能效高(但含调度/访存开销)极高(无冗余电路)
数据宽度固定(32/64 位)任意定制(如 3 位、12 位)
峰值算力极高(TFLOPS 级)中等
开发周期天~周周~月
重配置不可现场重配置

位宽定制是 FPGA 最被低估的优势。机器学习推理里的量化模型可能只需要 4 位整数运算,GPU 仍要按 8/16 位打包,FPGA 可以造出恰好 4 位的乘法器,把资源利用率翻倍。确定性延迟则是金融与工业控制的生命线——GPU 内核启动的微秒级抖动在高频交易里足以致命。

FPGA 的硬件结构

FPGA 由可编程逻辑块阵列与可编程互连构成,核心资源:

资源全称用途
LUTLook-Up Table实现任意组合逻辑函数
FFFlip-Flop存储状态,构成寄存器/流水线
DSPDSP Slice硬核乘加单元,做算术
BRAMBlock RAM片上块存储(几十 KB/块)
URAMUltra RAM更大的片上存储(Xilinx UltraScale+)
I/OI/O Block高速收发器、PCIe、HBM 接口

一个 6 输入 LUT 可以实现任意 6 输入 1 输出的逻辑函数。成千上万个 LUT + FF + DSP + BRAM 通过可编程互连连接,就构成一个可定制的数据通路。

典型现代 FPGA(如 Xilinx Alveo U250):
  ~170 万 LUT / ~340 万 FF
  ~12,000 DSP Slice
  ~2,700 块 BRAM(合计约 50 MB)
  多路 HBM2 / DDR4 接口 + PCIe Gen4

设计者在综合(synthesis)阶段把 HDL/HLS 代码映射到这些资源,布局布线(place & route)决定它们在芯片上的物理位置。时序收敛(timing closure)是核心挑战:设计必须满足目标时钟频率,否则综合器报时序违例。

两条开发路径

HDL:Verilog/VHDL

传统路径用硬件描述语言直接描述电路。控制精确、时序可预测,但开发慢、易出错。

// 一个 8 点滑动平均的流水线实现
module moving_avg (
    input  wire        clk,
    input  wire        rst,
    input  wire [15:0] din,
    input  wire        valid_in,
    output wire [15:0] dout,
    output wire        valid_out
);
    reg [15:0] shift0, shift1, shift2, shift3;
    reg [17:0] sum;
    reg        v0, v1, v2;

    always @(posedge clk) begin
        if (rst) begin
            {shift0, shift1, shift2, shift3} <= 0;
            v0 <= 0; v1 <= 0; v2 <= 0;
        end else begin
            shift0 <= din;
            shift1 <= shift0;
            shift2 <= shift1;
            shift3 <= shift2;
            v0 <= valid_in; v1 <= v0; v2 <= v1;
        end
    end

    assign sum = shift0 + shift1 + shift2 + shift3;
    assign dout = sum[17:2];      /* 除以 4,右移 2 位 */
    assign valid_out = v2;
endmodule

注意:没有循环、没有指令,每个时钟周期数据前进一级寄存器——这是流水线(pipelining) 的硬件表达,也是 FPGA 吞吐的来源。

HLS:高层次综合

HLS(High-Level Synthesis)把 C/C++/OpenCL 综合成硬件,开发效率高得多,代价是对硬件资源的控制不如 HDL 精细。

// Vitis HLS:向量加法的流水线实现
#include "hls_stream.h"

void vecadd(hls::stream<float> &a, hls::stream<float> &b,
            hls::stream<float> &c, int n) {
#pragma HLS INTERFACE axis port=a
#pragma HLS INTERFACE axis port=b
#pragma HLS INTERFACE axis port=c
    for (int i = 0; i < n; i++) {
#pragma HLS PIPELINE II=1          // 每周期接受一个新输入
        c.write(a.read() + b.read());
    }
}

关键 pragma:

Pragma作用
PIPELINE II=1流水化循环,每周期启动一次迭代
UNROLL展开循环,并行多份运算单元
ARRAY_PARTITION拆分数组,增加访存端口
DATAFLOW函数级流水,任务并行

II=1(Initiation Interval,启动间隔)表示流水线每周期吞一个元素,是吞吐的关键指标。若数据依赖或资源冲突导致 II>1,吞吐直接打折。

OpenCL / oneAPI

更上层的抽象用 OpenCL 或 SYCL/oneAPI 写内核,由工具链综合到 FPGA:

// SYCL 内核(oneAPI for FPGA)
queue.submit([&](handler &h) {
    h.parallel_for(range<1>(n), [=](id<1> i) {
        out[i] = in1[i] * in2[i] + bias[i];
    });
});

抽象越高,可移植性越好但性能调优空间越小。oneAPI 的跨架构愿景(CPU/GPU/FPGA 同一份 SYCL 代码)与 Kokkos 与 oneAPI 可移植编程 的讨论一脉相承。

数据搬运与内存

FPGA 加速的最大瓶颈往往不是计算,而是数据进出。板卡通过 PCIe 与主机通信,带宽有限(PCIe Gen4 x16 约 32 GB/s),而片上计算可能远超此速度。

内存层级

主机 DRAM ──PCIe──> 板卡 DDR/HBM ──> 片上 BRAM/URAM ──> 运算单元
           慢                  中                  快

优化的核心是让数据尽可能靠近运算单元、只搬一次。策略:

  • HBM 优先:带 HBM 的加速卡(如 Alveo U280)提供 TB/s 级板载带宽,避免 PCIe 瓶颈。
  • 片上缓存:把频繁访问的数据(如卷积核权重)放进 BRAM,复用时不重复访存。
  • DMA 流水:用 DMA 引擎在计算的同时预取下一批数据,重叠搬运与计算。
// 用流水线重叠 DMA 与计算(伪代码)
for (int tile = 0; tile < ntiles; tile++) {
#pragma HLS DATAFLOW
    dma_read(tile, buf_in);     // 预取 tile+1 的数据
    compute(buf_in, buf_out);   // 计算当前 tile
    dma_write(tile, buf_out);   // 写回上一 tile 结果
}

流水线与并行度

FPGA 的吞吐 = 并行度 × 时钟频率。提升并行度的手段是循环展开与数据流:

串行循环:    每次迭代 1 个运算,吞吐 = 1/周期
UNROLL=4:    4 个运算单元并行,吞吐 = 4/周期(资源 ×4)
DATAFLOW:    多个阶段流水,各阶段同时工作

资源是硬约束:展开越多,消耗的 DSP/LUT 越多,可能超出芯片容量或导致时序不收敛。调优是在「并行度」与「资源/频率」之间找平衡点。

设计方法论:从算法到电路

把算法搬上 FPGA,需要一次「软件思维到硬件思维」的转换。

识别可流水化的数据流

软件里的循环在硬件里对应流水线。设计的第一步是找出数据依赖链:哪些计算可以重叠,哪些必须等待。

软件循环:
  for i: y[i] = a[i]*b[i] + c[i]
        (每次迭代独立 → 可完全流水化,II=1)

依赖循环:
  for i: y[i] = y[i-1] + a[i]
        (存在跨迭代依赖 → 需重构为前缀和或放宽 II)

跨迭代依赖是流水线的天敌,它迫使 II>1,吞吐成倍下降。破解办法是循环变换(如把前缀和改成对数步的并行前缀)。

定点化

FPGA 的 DSP 擅长定点运算,浮点需消耗大量资源。把算法从浮点改到定点,往往能换来数倍资源节省:

分析数据动态范围 → 选定位宽与小数点位置 → 验证精度损失
例如:0~1 的概率值用 Q0.16(16 位小数)表示

定点化的风险是溢出与精度累积,需用软件模型先仿真验证,与 浮点精度 的误差分析方法相通。

空间架构

GPU 是「时间架构」(同一硬件分时执行多线程),FPGA 是「空间架构」(不同硬件单元同时执行)。设计时要把算法的并行性映射到物理空间:

时间架构(GPU):1000 个线程轮流用 128 个核心
空间架构(FPGA):为每个并行分支实例化一份独立电路

这意味着 FPGA 的性能优化是「复制硬件」,受限于芯片资源——并行度不是无限的,要在资源与吞吐间权衡。

典型加速场景

领域加速点优势来源
基因组比对Smith-Waterman、BLAST 过滤位宽定制、流水线、低延迟
高频交易行情解析、风控计算纳秒级确定性延迟
网络处理包分类、正则匹配线速处理、无中断
信号处理FFT、波束成形定点定制、实时流
机器学习推理量化推理、稀疏任意位宽、低延迟
密码学哈希、加解密位运算密集、流水线

基因组比对的经典案例:Smith-Waterman 动态规划在 CPU 上受限于内存带宽与串行依赖,FPGA 用流水线把 DP 矩阵沿对角线并行计算,配合位宽定制(得分用 8~16 位),能效比可达 CPU 的数十倍。这类「规则、流式、位宽可裁剪」的负载正是 FPGA 的主场。

部分重配置

「可重构」不只是上电时烧一次。动态部分重配置(Dynamic Partial Reconfiguration, DPR) 允许在运行时把芯片的一部分逻辑替换成新功能,其余部分继续运行:

静态区:PCIe 接口、DMA 引擎、内存控制器(始终存在)
动态区:加速内核(可运行时切换,如先跑 FFT 再换 AES)

应用场景:同一块 FPGA 按作业阶段切换加速器——训练阶段用矩阵内核,推理阶段换成量化内核,无需重启。这带来「时分复用」的硬件利用率,但也引入重配置延迟(毫秒级)与设计复杂度(需划分静态/动态区、管理部分比特流)。

部分重配置对多租户云 FPGA 尤其有价值:不同租户的加速器可分时占用同一块芯片,提高利用率。

工具链与生态

厂商器件工具链高层抽象
AMD/XilinxAlveo、VersalVivado、VitisHLS、SYCL
Intel/AlteraStratix、AgilexQuartusoneAPI、OpenCL
MicrochipPolarFireLiberoHLS
Lattice中小规模Diamond-

主流工作流(以 AMD Vitis 为例):

# 1. HLS 综合内核
v++ -c -t hw --platform xilinx_u250_gen3x16 --kernel vecadd vecadd.cpp -o vecadd.xo
# 2. 链接成比特流
v++ -l -t hw --platform xilinx_u250_gen3x16 vecadd.xo -o vecadd.xclbin
# 3. 主机程序加载并运行
./host vecadd.xclbin

生态的另一面是库与 IP 复用:厂商提供 FFT、矩阵运算、编解码等现成 IP,应用开发者可直接调用,避免从零造轮子。Vitis Libraries 与 oneAPI 的 oneMKL 都在推动这种复用,降低 FPGA 的入门门槛。

与 CPU/GPU 协同

FPGA 很少单独使用,而是作为异构系统的一环:

CPU:控制流、调度、I/O、复杂分支
GPU:大规模规则并行(矩阵乘、深度学习训练)
FPGA:低延迟、流式、定制位宽、确定性任务

例如网络包处理流水线:CPU 管理连接状态,FPGA 做线速过滤与转发,GPU 做深度包检测。三者通过 PCIe/NVLink/网络互联,各司其职。这种异构分工与 SIMD 向量化 在 CPU 上的思路一致——都是「把负载放到最适合的硬件单元上」。

性能与能效评估

评估 FPGA 不能只看峰值算力,而要看端到端指标:

指标说明
吞吐(ops/s)流水线深度 × 并行度 × 频率
延迟(μs/ns)数据从进入到离开的时间,含抖动
能效(ops/W)FPGA 的杀手锏,常达 GPU 的数倍
资源利用率LUT/DSP/BRAM 占用百分比
端到端加速比含数据搬运的实测值

端到端加速比才是最终裁判。一个计算内核在 FPGA 上比 GPU 快 5 倍,但若数据搬运耗时占 80%,端到端可能反而更慢。因此评估必须包含完整的数据路径,而非孤立的内核。

场景推荐硬件
大规模训练、高吞吐计算GPU
低延迟、确定性、流式FPGA
通用计算、复杂控制CPU
极低位宽推理、能效优先FPGA / ASIC

局限与选型

FPGA 并非万能:

  • 开发成本高:HDL/HLS 开发周期以周计,团队门槛高。
  • 峰值算力有限:不适合大规模稠密矩阵运算(GPU 的主场)。
  • 频率低:通常 200~500 MHz,靠并行度而非频率取胜。
  • 编译慢:布局布线可能耗时数小时,迭代成本高。
  • 可移植性差:代码与具体芯片绑定,换芯片需重新综合。

选型决策树:

需要低延迟/确定性? ── 是 ──> FPGA
        │ 否
需要极高能效且位宽可裁剪? ── 是 ──> FPGA(或 ASIC,量大时)
        │ 否
是大规模规则并行? ── 是 ──> GPU
        │ 否
             ──> CPU(多核 + SIMD)

只有当延迟、能效或位宽定制成为决定性因素时,FPGA 的开发成本才划算。把它当作异构工具箱里的一件专用武器,而非通用替代品。

小结

FPGA 用可重构逻辑换取 GPU 无法提供的确定性延迟与极致能效。理解 LUT/DSP/BRAM 的资源模型、HDL 与 HLS 两条开发路径、流水线与数据搬运的优化重心,以及「位宽定制」这一独特优势,你就能判断一个负载是否适合 FPGA。它的短板是开发成本与峰值算力,长处是低延迟、高能效与任意数据宽度。在现代异构系统里,CPU 管控制、GPU 管吞吐、FPGA 管延迟与能效,三者协同而非互替,才是性能与成本的最优解。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「hpc」更多文章

  1. 互连拓扑设计:Fat-tree、Torus 与 Dragonfly
  2. 检查点与重启策略
  3. 并行调试与死锁诊断工具链