首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

蚂蚁技术专家介绍RDMA技术砖题(二):收发机制

00、 作者介绍

RDMA(Remote Direct Memory Access)技术,即远端直接内存访问,是一种高性能网络通信技术。它利用网络适配器上的专用硬件,如网卡上的RDMA引擎,绕过操作系统内核,直接在网络传输层之下进行数据传输。这种直接内存访问的方式可以减少数据传输的延迟和CPU的负载,提高网络通信的效率。

RDMA的工作原理涉及发送端和接收端之间的通信。发送端将待发送的数据缓冲区注册到RDMA适配器的内存中,并将其描述符(包含了数据的地址、大小等信息)发送给接收端。接收端将接收缓冲区注册到RDMA适配器,并告知适配器接收缓冲区的地址。然后,发送端通过RDMA适配器将数据直接从发送缓冲区传输到接收缓冲区,而无需操作系统的干预。这个过程称为RDMA写操作。接收端可以通过RDMA读操作直接从发送端的内存中读取数据。

RDMA技术的优势在于其高带宽、低延迟和无CPU消耗的特点。它实现了零拷贝(Zero-copy),应用程序能够直接执行数据传输,无需涉及网络软件栈,从而降低了服务器的CPU和内存负担。此外,RDMA还支持分散/聚合条目(Scatter/gather entries support),这在进行远程内存读写操作时提供了更大的灵活性。

RDMA技术自1999年诞生之初主要用于HPC(高性能计算)领域,至今在超算top500榜单中仍有40%的集群使用该技术。随着技术的不断发展,RDMA技术已经逐渐从HPC领域扩展到通用数据中心领域,并广泛应用于AI训练、存储等场景。例如,微软在其GPT3大模型的训练中采用了RDMA技术。

作者:围城

云技术行业专家、蚂蚁集团技术专家

研究方向:Kubernetes云原生 & 计算引擎

知乎主页:https://www.zhihu.com/people/mastertTJ

文章链接:https://zhuanlan.zhihu.com/p/55142547

github:https://github.com/Tjcug

编辑:通信行业搬砖工

更多互联网技术与咨询分享,欢迎关注我们的公众号

01、 前言

RDMA指的是远程直接内存访问,这是一种通过网络在两个应用程序之间搬运缓冲区里的数据的方法。RDMA与传统的网络接口不同,因为它绕过了操作系统。这允许实现了RDMA的程序具有如下特点:

绝对的最低时延

最高的吞吐量

最小的CPU足迹 (也就是说,需要CPU参与的地方被最小化)

2、RDMA Verbs操作

使用RDMA, 我们需要有一张实现了RDMA引擎的网卡。我们把这种卡称之为HCA(主机通道适配器)。适配器创建一个贯穿PCIe总线的从RDMA引擎到应用程序内存的通道。一个好的HCA将在导线上执行的RDMA协议所需要的全部逻辑都在硬件上予以实现。这包括分组,重组以及流量控制和可靠性保证。因此,从应用程序的角度看,只负责处理所有缓冲区即可。

在RDMA中我们使用内核态驱动建立一个数据通道。我们称之为命令通道(Command Channel)。使用命令通道,我们能够建立一个数据通道(Data Channel),该通道允许我们在搬运数据的时候完全绕过内核。一旦建立了这种数据通道,我们就能直接读写数据缓冲区。

3、 Queue Pairs

RDMA操作开始于“搞”内存。当你在对内存进行操作的时候,就是告诉内核这段内存名花有主了,主人就是你的应用程序。于是,你告诉HCA,就在这段内存上寻址,赶紧准备开辟一条从HCA卡到这段内存的通道。我们将这一动作称之为注册一个内存区域(MR)。一旦MR注册完毕,我们就可以使用这段内存来做任何RDMA操作。在下面的图中,我们可以看到注册的内存区域(MR)和被通信队列所使用的位于内存区域之内的缓冲区(buffer)。

RDMA Memory Registration

struct ibv_mr {

struct ibv_context *context;

struct ibv_pd *pd;

void *addr;

size_t length;

uint32_t handle;

uint32_t lkey;

uint32_t rkey;

};

RDMA硬件不断地从工作队列(WQ)中去取工作请求(WR)来执行,执行完了就给完成队列(CQ)中放置工作完成通知(WC)。这个WC意思就是Work Completion。表示这个WR RDMA请求已经被处理完成,可以从这个Completion Queue从取出来,表示这个RDMA请求已经被处理完毕。

RDMA通信基于三条队列(SQ, RQ和CQ)组成的集合。其中, 发送队列(SQ)和接收队列(RQ)负责调度工作,他们总是成对被创建,称之为队列对(QP)。当放置在工作队列上的指令被完成的时候,完成队列(CQ)用来发送通知。

当用户把指令放置到工作队列的时候,就意味着告诉HCA那些缓冲区需要被发送或者用来接受数据。这些指令是一些小的结构体,称之为工作请求(WR)或者工作队列元素(WQE)。WQE的发音为"WOOKIE",就像星球大战里的猛兽。一个WQE主要包含一个指向某个缓冲区的指针。一个放置在发送队列(SQ)里的WQE中包含一个指向待发送的消息的指针。一个放置在接受队列里的WQE里的指针指向一段缓冲区,该缓冲区用来存放待接受的消息。

下面我们来看一下RDMA中的Work Request(SendWR和ReceWR)

RDMA Send Work Request请求

struct ibv_send_wr {

uint64_t wr_id;

struct ibv_send_wr *next;

struct ibv_sge *sg_list;

int num_sge;

enum ibv_wr_opcode opcode;

int send_flags;

uint32_t imm_data; /* in network byte order */

union {

struct {

uint64_t remote_addr;

uint32_t rkey;

} rdma;

struct {

uint64_t remote_addr;

uint64_t compare_add;

uint64_t swap;

uint32_t rkey;

} atomic;

struct {

struct ibv_ah *ah;

uint32_t remote_qpn;

uint32_t remote_qkey;

} ud;

} wr;

};

RDMA Receive Work Request请求

struct ibv_recv_wr {

uint64_t wr_id;

struct ibv_recv_wr *next;

struct ibv_sge *sg_list;

int num_sge;

};

RDMA是一种异步传输机制。因此我们可以一次性在工作队列里放置好多个发送或接收WQE。HCA将尽可能快地按顺序处理这些WQE。当一个WQE被处理了,那么数据就被搬运了。一旦传输完成,HCA就创建一个完成队列元素(CQE)并放置到完成队列(CQ)中去。相应地,CQE的发音为"COOKIE"。

RDMA Complete Queue Element

c++ struct ibv_wc { uint64_t wr_id;enum ibv_wc_status status;enum ibv_wc_opcode opcode;uint32_t vendor_err;uint32_t byte_len;uint32_t imm_data; /* in network byte order */uint32_t qp_num;uint32_t src_qp;int wc_flags;uint16_t pkey_index;uint16_t slid;uint8_t sl;uint8_t dlid_path_bits;};

4、 RDMA Send/Receive

让我们看个简单的例子。在这个例子中,我们将把一个缓冲区里的数据从系统A的内存中搬到系统B的内存中去。这就是我们所说的消息传递语义学。接下来我们要讲的一种操作为SEND,是RDMA中最基础的操作类型。

4.1 第一步

第1步:系统A和B都创建了他们各自的QP的完成队列(CQ), 并为即将进行的RDMA传输注册了相应的内存区域(MR)。系统A识别了一段缓冲区,该缓冲区的数据将被搬运到系统B上。系统B分配了一段空的缓冲区,用来存放来自系统A发送的数据。

4.2 第二步

第二步:系统B创建一个WQE并放置到它的接收队列(RQ)中。这个WQE包含了一个指针,该指针指向的内存缓冲区用来存放接收到的数据。系统A也创建一个WQE并放置到它的发送队列(SQ)中去,该WQE中的指针执行一段内存缓冲区,该缓冲区的数据将要被传送。

4.3 第三步

第三步:系统A上的HCA总是在硬件上干活,看看发送队列里有没有WQE。HCA将消费掉来自系统A的WQE, 然后将内存区域里的数据变成数据流发送给系统B。当数据流开始到达系统B的时候,系统B上的HCA就消费来自系统B的WQE,然后将数据放到该放的缓冲区上去。在高速通道上传输的数据流完全绕过了操作系统内核。

4.4 第四步

第四步:当数据搬运完成的时候,HCA会创建一个CQE。这个CQE被放置到完成队列(CQ)中,表明数据传输已经完成。HCA每消费掉一个WQE, 都会生成一个CQE。因此,在系统A的完成队列中放置一个CQE,意味着对应的WQE的发送操作已经完成。同理,在系统B的完成队列中也会放置一个CQE,表明对应的WQE的接收操作已经完成。如果发生错误,HCA依然会创建一个CQE。在CQE中,包含了一个用来记录传输状态的字段。

我们刚刚举例说明的是一个RDMA Send操作。在IB或RoCE中,传送一个小缓冲区里的数据耗费的总时间大约在1.3µs。通过同时创建很多WQE, 就能在1秒内传输存放在数百万个缓冲区里的数据。

5、 总结

在这篇文章中,我们学习了如何使用RDMA verbs API。同时也介绍了队列的概念,而队列概念是RDMA编程的基础。最后,我们演示了RDMA send操作,展现了缓冲区的数据是如何在从一个系统搬运到另一个系统上去的。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OP543pgiN9F1swQt67y6AldA0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券