
摘要在AI大模型训练与高性能计算中RDMA是实现零拷贝、内核旁路的核心技术。本文将带你彻底搞懂RDMA最核心的四大抽象保护域PD、内存区域MR、完成队列CQ与队列对QP。我们将从底层硬件视角剖析它们的工作原理、状态机流转并结合Verbs API代码与GPUDirect RDMA场景揭开智能网卡高效通信的神秘面纱。大家好 欢迎来到我的技术博客。最近AI大模型训练如火如荼动辄千卡集群的背后NCCL和RDMA绝对是功不可没的“幕后英雄”。很多同学在面试或者做底层网络优化时都会被问到“RDMA到底是怎么做到微秒级延迟和零拷贝的”要回答这个问题我们就必须深入智能网卡RNIC的内部搞懂RDMA最核心的四大抽象对象PD保护域、MR内存区域、CQ完成队列和QP队列对。今天我们就用大白话底层原理把这四大金刚扒得干干净净一、 PD与MR安全沙箱与内存的“通行证” ️在RDMA的世界里硬件直接操作内存这听起来很爽但如果没有安全机制岂不是乱套了这就需要PD和MR出场了。1. PDProtection Domain硬件级安全沙箱PD保护域本质上是一个逻辑上的安全边界。你可以把它想象成公司里的“独立保密办公区”。隔离性同一个PD下的资源如QP、MR可以互相访问但跨PD的访问会被硬件直接拦截。作用确保多个应用程序共享同一张智能网卡时不会发生内存越界和互相踩踏。在DOCA或Verbs API中创建任何通信资源前都必须先创建一个PD。2. MRMemory Region内存的“快递单” RDMA的核心是“远程直接内存访问”但网卡怎么知道哪块内存是可以读的这就需要把内存注册为MR。Pin住物理内存注册MR时内核会将这块虚拟内存“钉”在物理内存上Page Pinning防止被Swap换出。生成密钥注册成功后硬件会生成LKey本地访问密钥和RKey远程访问密钥。这就好比给这块内存贴上了防伪标签和快递单号。进阶场景GPUDirect RDMA在AI训练中数据都在GPU显存里。通过GDR技术我们可以直接把GPU显存注册为MRRNIC通过PCIe P2P直接读写显存彻底 bypass 掉主机内存实现真正的“零中转”。二、 QP与CQ通信的心脏与神经中枢 ⚡如果说PD和MR是基础设施那QP和CQ就是真正干活的“打工人”。1. QPQueue Pair硬件直驱的通信端点QP队列对是RDMA通信的核心载体由SQ发送队列和RQ接收队列组成。用户态狂欢SQ和RQ都映射在用户态内存中。应用程序通过ibv_post_send等API直接把WQE工作请求元素写入队列完全不需要陷入内核态这就省去了昂贵的上下文切换开销。状态机流转QP不是创建就能用的它必须经历严格的状态机转换RESET → INIT → RTR (Ready to Receive) → RTS (Ready to Send)。在INIT阶段绑定端口和PD在RTR阶段交换远端QP号QPN和PSN包序号在RTS阶段设置超时和重传机制。2. CQCompletion Queue异步任务的通知中心RDMA操作是异步的CPU把WQE扔进SQ后就可以去干别的事了。那怎么知道数据发完没CQE完成队列元素当网卡硬件完成一次DMA读写或网络收发后会生成一个CQE扔进与该QP绑定的CQ中。轮询Polling机制用户态程序通过ibv_poll_cq疯狂轮询CQ一旦拿到CQE就知道“快递已送达”从而触发下一步业务逻辑。这种轮询模式虽然吃一点CPU但换来了极致的低延迟。三、 四大对象协同一次RDMA Write的奇妙旅程 为了让大家更直观地理解我们用表格对比一下传统TCP和RDMA在发送数据时的差异并梳理一次RDMA Write的完整流程。对比维度传统 TCP/IP 网络RDMA (RoCEv2 / IB)数据拷贝用户态 → 内核态 → 网卡 (多次拷贝)用户态 → 网卡 (零拷贝DMA直读)内核参与全程参与协议栈、上下文切换数据面完全旁路仅控制面初始化参与CPU开销极高中断、软中断、协议计算极低硬件卸载CPU仅轮询CQ延迟50~100 微秒 1 微秒 RDMA Write 核心流程控制面准备APP创建 Context - PD - MR - CQ - QP并完成QP状态机转换RTS。投递请求APP构造 Write WR填入远端虚拟地址和RKey投递到本地 QP 的SQ。硬件接管RNIC硬件扫描SQ拿到WQE通过DMA直接从本地MR读取数据。网络传输RNIC封装RoCEv2/IB报文打入网络。远端落地远端RNIC收到报文校验RKey后直接通过DMA将数据写入远端MR对应的内存中。完成通知远端RNIC生成CQE放入CQ远端APP轮询CQ发现数据已到直接计算全程远端CPU在“睡大觉”。四、 动手实战Verbs API 核心对象创建与追踪 ️光说不练假把式。我们来看看在代码中这四大对象的创建顺序和QP状态机是怎么玩的。// 1. 获取设备上下文structibv_context*ctxibv_open_device(device);// 2. 创建保护域 (PD)structibv_pd*pdibv_alloc_pd(ctx);// 3. 注册内存区域 (MR)// 将一块4MB的内存注册为MR赋予本地和远程读写权限structibv_mr*mribv_reg_mr(pd,buf,4*1024*1024,IBV_ACCESS_LOCAL_WRITE|IBV_ACCESS_REMOTE_WRITE);// 此时 mr-lkey 和 mr-rkey 就准备好了// 4. 创建完成队列 (CQ)structibv_cq*cqibv_create_cq(ctx,100,NULL,NULL,0);// 5. 创建队列对 (QP)structibv_qp_init_attrqp_init_attr{.send_cqcq,.cap{.max_send_wr100,.max_recv_wr100}};structibv_qp*qpibv_create_qp(pd,qp_init_attr);// 6. QP 状态机流转 (以客户端连接为例)// RESET - INITibv_modify_qp(qp,attr,IBV_QP_STATE|IBV_QP_PKEY_INDEX|IBV_QP_PORT);// INIT - RTR (需要填入远端QP号、GID、PSN等)ibv_modify_qp(qp,attr,IBV_QP_STATE|IBV_QP_AV|IBV_QP_PATH_MTU|...);// RTR - RTSibv_modify_qp(qp,attr,IBV_QP_STATE|IBV_QP_TIMEOUT|IBV_QP_RETRY_CNT|...);极客小技巧用 eBPF 追踪 QP 状态机在Linux下如果你用的是SoftRoCE或者真实的mlx5网卡可以通过bpftrace挂载内核的rdma_rxe或mlx5_ib模块实时追踪QP的状态转换bpftrace-efentry:rdma_rxe:rxe_modify_qp { printf(QP State Transition to: %d\n, args-attr-qp_state); }看着终端里打印出1(INIT) - 2(RTR) - 3(RTS)那种掌控底层硬件的快感真的谁用谁知道五、 总结与互动 今天我们深度拆解了RDMA的四大核心抽象PD划定安全边界MR锁定物理内存并分发密钥QP作为用户态与硬件直驱的桥梁承载WQECQ负责异步完成事件的轮询通知。正是这四者的精妙配合加上智能网卡强大的DMA引擎和硬件协议卸载能力才造就了RDMA在AI大模型训练、高频交易等极致性能场景中的统治地位。大家在平时使用RDMA或者调优NCCL时有没有遇到过什么“坑”或者对GPUDirect RDMA的底层DMA映射还有什么疑问欢迎在评论区留言我们一起探讨交流如果觉得这篇文章对你有帮助别忘了点赞、收藏、关注三连哦我们下期再见推荐标签#RDMA #InfiniBand #智能网卡 #GPUDirect #Verbs #高性能网络 #AI基础设施 #底层原理本文为RDMA智能网卡技术知识系列文章。首发于CSDN转载请注明出处。