cpu rdma 与 gpunetio 的关系

gpunetio, 是类似cpu app doca sender,receiver 过程的 gpu化,现在探究两者的联系。

GPUNetIO 就是把我们 demo 里 CPU 扮演的那个"App"角色,整体搬到 GPU 线程(CUDA kernel)里 ------同一条 构造WQE → post到SQ → 敲门铃 → 网卡DMA → 写CQE → 轮询CQ 流水线,一步都没少,只是干活的人换了。CPU 没有消失,而是从"数据面"退到了"控制面"。

一、同一个流水线,两边对照

流水线环节 CPU 版 demo(已完成) GPUNetIO 版
注册内存(MR) posix_memalign + doca_mmap(主机内存) cudaMalloc(显存)+ 注册(GPUDirect RDMA,网卡直接 DMA 到显存)
QP 位置 QP 在网卡上,SQ/RQ/CQ 在主机内存 SQ/RQ/CQ 映射到 GPU 显存,GPU 线程直接读写
构造 WQE / post CPU 调 doca_rdma_task_send_allocate_init + doca_task_submit GPU kernel 内的线程调同一族 API 的任务提交(GPUNetIO 提供了设备侧版本的 submit)
敲门铃 submit 内部完成 GPU 线程直接写映射进 GPU 地址空间的门铃寄存器(PCIe BAR),CPU 完全不参与
收 CQE doca_pe_progress() 轮询 CQ → 回调 GPU kernel 内的轮询循环直接读显存里的 CQE(没有 PE、没有回调函数)
数据处理 回调里 printf / memcmp kernel 里拿到数据后直接接着算(这就是意义所在:零拷贝进计算)

关键收益就在最后一行:数据从网线进显存,GPU 算完直接发回网线,全程不落地主机内存、CPU 一次都不碰数据。

二、需要改变的具体地方(改动清单)

  1. 内存全部换 CUDA 显存 :收发缓冲区用 cudaMalloc,mmap 注册时走 GPU 内存路径。这是"GPUDirect RDMA"的本体。

  2. 队列搬到 GPU :创建 doca_rdma(或以太网模式的 doca_eth_txq/doca_eth_rxq)时指定队列导出到 GPU 显存,让 GPU 线程够得着 WQE/CQE。

  3. 提交与轮询搬进 kernel :CUDA kernel 常驻运行(persistent kernel),里面就是一个循环:提交任务/发包 → 轮询完成计数 → 处理数据 → 再提交。PE 没了------PE 是 CPU 线程亲和的事件引擎,GPU 侧用不上;回调也没了,换成 kernel 里自己 poll、自己计数。

  4. 连接建立留在 CPU :开卡、建 QP、doca_rdma_export/connect 握手、注册显存------这些控制面操作仍由 CPU 在 kernel 启动前完成 ,然后通过参数/CUDA 事件把"连接已就绪、队列地址"等交给 kernel。这也是 GPUNetIO 的固定分工:CPU 管控制面,GPU 管数据面。

  5. CPU↔GPU 同步换机制 :demo 里用 volatile int send_done 让回调通知主线程;GPUNetIO 里用 GPUNetIO 自带的 GPU 信号量/等待原语(doca_gpu 同步对象)+ CUDA 事件,比如 CPU 发令"开始收发"、kernel 回报"已完成 N 个"。

  6. (可选)以太网模式 :如果不走 RDMA 而跑裸以太网,QP 换成 doca_eth_txq/rxq(无连接,按 burst 收发包),配 doca_flow 做报文 steering------这是 GPUNetIO 另一种形态,适合自定义协议。

三、语义不变的部分

  • QP/RC 连接/EXPORT-CONNECT 握手、先 post RECEIVE 再 SEND 的顺序约束、CQE 语义------一模一样;
  • WQE/CQE 的字段含义、门铃机制、环形队列------硬件层面没有任何区别。

所以在 CPU demo 里搞清楚的那套模型,在 GPUNetIO 里是 1:1 复用的,改的只是"谁来 post、谁来 poll、内存住哪"。建议路径:先按官方 doca-samples 仓库里的 GPUNetIO RDMA 收发示例跑通(结构上会看到很多眼熟的函数名),再把 demo 的 loopback 逻辑搬进去------注意 kernel 里的轮询循环必须有退出条件和超时,否则 kernel 挂死时你连报错都看不到,调试难度比 CPU 版高一个量级。

相关推荐
垆边人似月.17 小时前
RDMA项目踩坑(一):为什么最后一块数据必须使用实际长度?
网络·c/c++·rdma·高性能io·tcp与rdma
垆边人似月.21 小时前
RDMA 文件传输踩坑(二):为什么 `sleep()` 不能保证接收端准备好了?
linux·服务器·网络·rdma
孙琦Ray1 天前
Meta 把 AI 网络 RDMA 传输层开源了
meta·开源·rdma·ai 网络·ocp 全球峰会·数据中心交换机
Eloudy2 天前
从源码 安装sglang
gpu
Eloudy2 天前
SGLang 的组成结构与基本工作原理
llm·gpu·sglang
Eloudy2 天前
`ibv_get_device_list` 实现分析
网络·gpu·rdma
蒸鱼Yuzheng2 天前
移动端 Overdraw 治理:从单帧热图到屏幕空间预算
性能优化·gpu·renderdoc·overdraw·移动端渲染
Eloudy2 天前
MLNX_OFED 源码补齐、Debug/Release 构建命令与修改记录
gpu·rdma
Smoothcloud润云3 天前
远程纳管GPU怎么安全升级?驱动、组件灰度与回滚实战
人工智能·深度学习·安全·gpu算力·gpu·数据库管理员
鲨鱼辣钊3 天前
KVM显卡直通实战_RTX4090分时复用
gpu·kvm·vfio