RDMA 与RoCE v2

一套最精简、能直接落地的 RDMA / RoCE v2 工程资料包,包含:关系再梳理、报文结构、FPGA 实现框架、x86 侧最简可用 C 代码、测试命令。

一、RDMA ↔ RoCE v2 关系(最终版)

  • RDMA :一套远程直接内存访问技术标准(API + 语义)
    • 零拷贝、内核旁路、CPU 不参与数据搬运
  • RoCE :RDMA over Converged Ethernet,以太网承载 RDMA
    • RoCE v1:L2 以太网,不可路由
    • RoCE v2:L3 UDP/IP 封装,可路由,现在唯一实用版本

可以记成:

RDMA = 能力 RoCE v2 = 以太网环境下跑 RDMA 的报文格式


二、RoCE v2 报文封装结构

plaintext

复制代码
以太网头 + IP头 + UDP头 + GRH + BTH + RDE + 载荷
  • GRH:Global Routing Header(RoCE v2 特有,用于路由)
  • BTH:Base Transport Header
  • RDE:RDMA 扩展头(Send/Read/Write/Atomic)

特点:

  • 就是一个标准 UDP 报文 ,端口默认 4791
  • 普通交换机可转发,支持三层路由
  • 无损网络建议开启 PFC / ECN(不强制,但延迟更稳)

三、FPGA 实现 RoCE v2 最小结构

你用 FPGA 做 RNIC(RDMA 网卡),核心就这几部分:

  1. PCIe DMA 引擎
    • 与 x86 主机内存交互(QP 队列、WQE、CQE)
  2. QP 管理模块(Queue Pair)
    • SQ + RQ:发送 / 接收队列
    • CQ:完成队列
  3. RoCE v2 协议栈
    • 封装 / 解封装 GRH/BTH/UDP/IP
    • 校验和卸载
  4. 以太网 MAC/PCS
    • 25G/100G 以太网时序处理
  5. 可靠传输控制(可选)
    • ACK、重传、滑动窗口(RC 模式)

数据流:

plaintext

复制代码
x86 提交 WQE → FPGA QP → 封装 RoCE v2 → 以太网发送

四、x86 侧 RDMA (ibverbs) 最简发送代码

依赖:libibverbs

c

运行

复制代码
#include <infiniband/verbs.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUF_SIZE 1024

int main() {
    struct ibv_device **dev_list;
    struct ibv_context *ctx;
    struct ibv_pd *pd;
    struct ibv_mr *mr;
    struct ibv_cq *cq;
    struct ibv_qp *qp;
    struct ibv_qp_init_attr qp_attr = {};
    char *buf = malloc(BUF_SIZE);
    struct ibv_wc wc;
    int ret;

    // 1. 打开 RDMA 设备
    dev_list = ibv_get_device_list(NULL);
    ctx = ibv_open_device(dev_list[0]);
    ibv_free_device_list(dev_list);

    // 2. 保护域 + 注册内存
    pd = ibv_alloc_pd(ctx);
    mr = ibv_reg_mr(pd, buf, BUF_SIZE,
        IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_WRITE);

    // 3. 创建 CQ + QP
    cq = ibv_create_cq(ctx, 128, NULL, NULL, 0);
    qp_attr.send_cq = cq;
    qp_attr.recv_cq = cq;
    qp_attr.qp_type = IBV_QPT_RC;  // RC = 可靠连接
    qp = ibv_create_qp(pd, &qp_attr);

    // 4. QP 状态切换 (INIT->RTR->RTS)
    // 略(需要对方 QP 信息,实际代码需交换 GID/QP 号)

    // 5. 发送数据
    memset(buf, 0x5a, BUF_SIZE);
    struct ibv_sge sge = {
        .addr = (uint64_t)buf,
        .length = BUF_SIZE,
        .lkey = mr->lkey
    };
    struct ibv_send_wr wr = {
        .wr_id = 0x1234,
        .sg_list = &sge,
        .num_sge = 1,
        .opcode = IBV_WR_SEND,
        .send_flags = IBV_SEND_SIGNALED
    };
    struct ibv_send_wr *bad_wr;
    ret = ibv_post_send(qp, &wr, &bad_wr);

    // 6. 等待完成
    while (ibv_poll_cq(cq, 1, &wc) < 1);
    printf("RDMA Send 完成, status=%d\n", wc.status);

    return 0;
}

编译:

bash

运行

复制代码
gcc rdma_test.c -o rdma_test -libverbs

五、RDMA 常用操作(你和 FPGA 通信最常用)

  1. IBV_WR_SEND
    • 主动发消息,对方需提前 posted recv
  2. IBV_WR_WRITE
    • 直接写对方内存,对方 CPU 完全无感知
    • 最适合 FPGA → x86 低延迟上行
  3. IBV_WR_READ
    • 直接读对方内存
  4. Atomic
    • 原子加 / 比较交换,用于同步

实时通信首选:WRITE + 少量 SEND 同步


六、测试 RDMA 延迟 / 带宽命令

安装:perftest

bash

运行

复制代码
# 服务端(FPGA 或另一台机器)
ib_write_bw -d rdma0 -R  # RoCE v2
ib_write_lat -d rdma0 -R

# 客户端
ib_write_bw -d rdma0 -R 192.168.1.100
ib_write_lat -d rdma0 -R 192.168.1.100

典型结果:

  • 写延迟:1us 左右
  • 抖动:< 100ns
  • 100G 带宽可跑满

七、你接下来最该做的三件事

  1. 在 FPGA 上实现 RoCE v2 + QP + DMA
  2. x86 用 ibverbsRDMA_WRITE 上行
  3. 配合之前的系统优化(isolcpus、关闭节能、巨页)
相关推荐
tju新生代魔迷1 天前
Verilog HDL 学习笔记(十)| 第10章 时序和延迟
笔记·学习·fpga开发
aprilaaaaa1 天前
(TC397 学习笔记)二、ICU和TIM的时钟计算
笔记·学习·fpga开发
X_xcccc2 天前
2026高端FPGA开发平台权威评测与选型指南
fpga开发
威嵌神州2 天前
军工加固计算机七大核心特性解析|国产化、宽温、强加固工程实现
嵌入式硬件·计算机网络·fpga开发
FPGA小迷弟2 天前
高云半导体深度解读:国产FPGA车规赛道的领跑者
fpga开发
努力搬砖的小H2 天前
FPGA应用技巧之Block Design基本使用方法
功能测试·fpga开发·zynq·block design
ALINX技术博客2 天前
【黑金云课堂】FPGA技术教程FPGA 基础:HDMI视频输入与环路输出实验
fpga开发·音视频
hahaha60162 天前
HLS高层次综合设计--axi之burst纠偏
开发语言·算法·fpga开发·c#
珞光电子USRP SDR软件无线电平台3 天前
国产嵌入式SDR平台LW-E320-G详解:射频、FPGA、ARM架构与应用选型
arm开发·fpga开发·架构
FPGA小迷弟3 天前
【硬核通俗】FPGA实现SDR软件无线电完整技术解析(原理+架构+实战)
fpga开发·dsp开发·sdr·无线电