按 "硬件→系统→驱动→软件→FPGA→验证" 顺序,全部是工程可用配置,复制粘贴就能用。
一、硬件与 BIOS 必开配置(先做这个)
1. BIOS 关闭一切节能、开启性能
进入 BIOS 关闭以下项(不同主板名称略有差异):
- C-State、C1E、C6、C7
- P-State、SpeedStep、睿频(可选锁固定频率)
- ASPM(PCIe 节能)
- 虚拟化 VT-d / IOMMU 必须开启(用于 VFIO/DPDK)
- PCIe 最大 payload:设为 1024B / 2048B / 4096B(按 FPGA 支持最大)
- PCIe 最大读请求 MRRS:同 MPS
2. 物理安装
- FPGA 网卡插在 CPU 直连 PCIe slot(通常离 CPU 最近的槽)
- 不要插在 PCH 桥接的槽
- 链路速率确认:
lspci -vvv | grep LnkSta应为 Gen4 x16 / Gen3 x16
二、Linux 内核启动参数(最关键)
编辑 /etc/default/grub,在 GRUB_CMDLINE_LINUX_DEFAULT 加入:
plaintext
isolcpus=1,2,3 \
nohz_full=1,2,3 \
rcu_nocbs=1,2,3 \
intel_pstate=disable \
processor.max_cstate=0 \
idle=poll \
pcie_aspm=off \
iommu=on iommu=pt \
hugepagesz=1G hugepages=4 \
default_hugepagesz=1G \
tsc=reliable \
nmi_watchdog=0 \
irqaffinity=0
然后执行:
bash
运行
grub2-mkconfig -o /boot/grub2/grub.cfg
reboot
三、系统级优化(开机执行)
1. 关闭干扰服务
bash
运行
systemctl stop irqbalance
systemctl disable irqbalance
systemctl stop firewalld
systemctl disable firewalld
swapoff -a
echo 0 > /proc/sys/kernel/nmi_watchdog
echo 0 > /proc/sys/kernel/watchdog
2. 网卡中断全部绑到隔离核外
bash
运行
# 查看 FPGA 网卡 IRQ
grep eth /proc/interrupts
# 绑到核心0
echo 1 > /proc/irq/XXX/smp_affinity
3. 巨页确认
bash
运行
grep -E 'HugePages_Total|Hugepagesize' /proc/meminfo
必须看到:
Hugepagesize: 1048576 kB(1G)HugePages_Total: 4
四、DPDK / VFIO 绑定 FPGA 网卡(用户态驱动)
1. 加载 VFIO
bash
运行
modprobe vfio
modprobe vfio-pci
2. 解绑内核驱动
bash
运行
# 先查 BDF
lspci | grep FPGA
# 解绑
echo 0000:xx:xx.x > /sys/bus/pci/devices/0000:xx:xx.x/driver/unbind
# 绑定 vfio-pci
echo 0000:xx:xx.x > /sys/bus/pci/drivers/vfio-pci/bind
3. DPDK 初始化示例
bash
运行
./dpdk-devbind.py --bind=vfio-pci 0000:xx:xx.x
./testpmd -l 1-2 -n 4 --socket-mem=1024 -- --nb-cores=2
核心绑定:-l 1-2 对应 isolcpus 核
五、CPU 核心与线程策略(代码层面)
1. 线程绑核 + 实时优先级
c
运行
// C 语言绑核示例
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(1, &cpuset);
pthread_setaffinity_np(pthread_self(), sizeof(cpuset), &cpuset);
// 实时调度
struct sched_param param = {.sched_priority = 99};
sched_setscheduler(0, SCHED_FIFO, ¶m);
2. 内存属性
-
DMA 缓冲区用 1G 巨页
-
设为:写合并 WC / 非临时 NT
-
避免缓存伪共享:结构体按 64B 对齐
c
运行
struct pkt __attribute__((aligned(64)));
六、FPGA 侧优化(决定性)
1. PCIe DMA 配置
- 使用 AXI DMA / XDMA ,开启 SG 模式
- 描述符预取,流水线传输
- FPGA 内部用 Stream FIFO + BRAM 缓冲,减少突发中断
2. 协议卸载(优先级从高到低)
- RDMA(RoCEv2):单边读写,x86 零参与
- UDP 硬件卸载:校验和、流控全在 FPGA
- 时间敏感网络 TSN:802.1Qbv 时间门控
3. 确定性设计
- 报文处理 固定周期流水线
- 硬件打时间戳(PTP/TSN)
- 不使用软核 CPU 做数据通路
七、中断 vs 轮询策略(直接选)
低延迟优先(<2μs)
- 纯轮询 polling
- 禁用 MSI-X
- 隔离核死循环查 FIFO 空满
平衡性能
- MSI-X + 中断上半部轮询
- 中断绑隔离核
- 批量 DMA 完成再通知
八、实测验证命令(判断是否优化到位)
1. PCIe 状态
bash
运行
lspci -vvv | grep -A5 LnkSta
确保:
- Speed 为 Gen3/Gen4
- Width x16
- ASPM disabled
2. 核心隔离
bash
运行
ps -eo pid,psr,cmd | grep -E 'testpmd|your_app'
看 PID 是不是固定在 1/2/3 核
3. 延迟测试
- DPDK testpmd 收发包延迟
- FPGA 内部寄存器回环测试
- PTP 时间戳差
九、最终优化目标(典型可达到)
- 端到端延迟:< 1.5 μs
- 抖动:< 100 ns
- 无调度抖动、无页缺失、无中断漂移