RDMA是一种使一台计算机可以直接将数据从内存通过网络传送到另一台计算机内存中的技术,其流程是首先将数据通过DMA方式拷贝到NIC(网卡),再通过网络传输到远端NIC,然后直接到达远端内存,而无需操作系统多次在缓冲区指间拷贝数据和CPU参与,因而能腾出总线空间和 CPU周期用于改进应用系统性能,从而减少对带宽和处理器开销的需要,显著降低了时延。RDMA的核心优势是内核旁路和零拷贝技术。
下图给出了RDMA与TCP/IP的对比,这幅图清楚地表明了RDMA的零拷贝特性,二者的详细对比后面给出。
下图给出了RDMA的内核旁路特性:
目前,有三种支持RDMA的技术:IB(InfiniBand)、RoCE(RDMA over Converged Ethernet)、以太网iWARP(the Internet Wide Area RDMA Protocol)。这三种技术使用同一API,但它们有着不同的物理层和链路层。
IB: 原生支持RDMA,它从硬件级别保证可靠传输;
iWARP: 基于 以太网之上的TCP or SCTP 做 RDMA,利用 TCP or SCTP 达到可靠传输,对网络设备的要求比较少;
RoCE: 基于以太网做 RDMA,消耗的资源比 iWARP 少,支持的特性比 iWARP 多,需要额外做可靠传输。
在以太网解决方案中,RoCE相对于iWARP来说有着明显的优势,这些优势体现在延时、吞吐率和 CPU负载。二者对比:
RoCE |
UDP |
IP |
以太网 |
iWARP |
TCP(无TCP/IP流量控制和管理) |
IP |
以太网 |
Mellanox公司提供了两个动态链接库ib_verbs和rdma_cm(连接管理器库,包含了对ib_verbs的封装),通过verbs API 对硬件进行访问。下面描述被暴露在操作系统编程接口的功能。
为了执行RDMA操作,首选需要建立与远程主机的连接和适当的认证。实现这些的机制是队列对(QP) 。与标准的IP协议栈类似,一个QP大概等同于一个套接字(socket)。QP需要在连接两端进行初始化。连接管理器(CM)用来在QP建立之前进行QP信息的交换。一旦一个QP建立起来,verbs API就可以用来执行RDMA读/写和原子操作,与套接字的读/写类似的连续收/发操作也能执行。
QP中的传输使用Work Request(WR)进行,而非数据流的形式。应用程序在Work Request中指定收发数据的地址(RDMA对数据存放的地址有要求,这些地址在使用前,必须注册到IB驱动中)。除此之外,QP的Send Queue和Receive Queue还需要配备一个Completion Queue,这个Completion Queue用来保存WR处理结果(发送或者收到),WR信息可以从Completion Queue中的Work Completion(WC)中获得。
进一步讲,WR还分为Receive WR和Send WR,Receive WR用来指定另一端发过来的数据存放位置,Send WR则是实际的数据发送请求。在主机中注册的内存类型(ib_access_flags)决定了远端client操作主机内存的方式。如果具有Remote Access权限,则可以直接在Send WR中指定待操作的地址(此为RDMA Read/Write操作),主机无需参与操作;否则Send WR对远端地址没有控制权,即发送的数据的存放地址不由Send WR决定(只能Send/Recv操作),主机需要处理请求。使用哪种操作方式可以在ib_wr_opcode中指定。
1) 发送/带立即数(Immediate)的发送
发送操作可以把数据发送到远程QP的接收队列里。接收端必须已经事先注册好了用来接收数据的缓冲区。发送者无法控制数据在远程主机中的放置位置。在特定设置下,一个4字节的立即数可以和数据缓冲一起被传送。这个立即数发送到接收端是作为接收的通知,不包含在数据缓冲之中。
2) 接收
这是与发送操作相对的操作。接收主机被告知接收到数据缓冲区,还可能附带一个立即数。接收端应用程序负责接收缓冲区的维护和注册。
3) RDMA读
从远程主机读取部分内存。调用者指定远程虚拟地址,像本地内存地址一样用来拷贝。在执行RDMA操作之前,远程主机必须提供适当的权限来访问它的内存。一旦权限设置完成,RDMA读操作就可以在对远程主机没有任何通知的条件下执行。不管是RDMA读还是RDMA写,远程主机都不会意识到操作正在执行(除了权限和相关资源的准备操作)。
4) RDMA写/带立即数的RDMA写
与RDMA读类似,只是数据写到远程主机中。RDMA写操作在执行时不通知远程主机。然而,带立即数的 RDMA写操作会将立即数通知给远程主机。
5) 原子取和加/原子比较和交换
这些是RDMA操作的原子操作扩展。原子取和加操作原子性地将特定虚拟地址中的数加上特定的值。被加之前的数返回给调用者。原子比较和交换操作原子性地将特定虚拟地址中的数与另一个特定的数加比,如果它们相等,那么另一个特定的数将会被存在上述的特定虚拟地址中。
在建立一个QP的时候,有几种不同的传输模式可供选择。每种模式中可用的操作如下表所示。 RD操作在此API中不支持。
一个QP只和一个另外的QP相连。消息通过一个QP的发送队列可靠地传输到另一个QP的接收队列。数据包按序交付。RC连接很类似于TCP连接。
一个QP只和一个另外的QP相连。连接是不可靠的,所以数据包有可能会丢失。传输层不会出错的消息进行重传,错误处理必须由高层的协议来进行。
一个QP可以和其它任意的UD QP进行数据传输和单包数据的接收。不保证按序性和交付性。交付的数据包可能被接收端丢弃。支持多播消息(一对多)。连接很类似于UDP连接。
RDMA read/write 称为one-sided操作(也叫server-bypass),RDMA Send/Recv 称为two-sided操作(也叫server-reply,因为它是request-reply模式,需要reply)。one-sided操作相比于Two-sided的好处是释放了主机端的CPU,降低了传输的Latency。因为one-sided方式在主机端无需生成WQE,也就不需要处理Work Completion。
下组图给出了一次RDMA Send/Recv的示意图:
1)发送请求(SR)
SR定义了数据的发送量、从哪里、发送方式、是否通过RDMA、到哪里。
2)接收请求(RR)
RR定义用来放置通过非RDMA操作接收到的数据的缓冲区。如没有定义缓冲区,并且有个传输者 尝试执行一个发送操作或者一个带立即数的RDMA写操作,那么接收者将会发出接收未就绪的错误(RNR)。
3)完成队列(CQ)
完成队列包含了发送到工作队列(WQ)中已完成的工作请求(WR)。每次完成表示一个特定的 WR执行完毕(包括成功完成的WR和不成功完成的WR)。完成队列是一个用来告知应用程序已结束的工作请求的信息(状态、操作码、大小、来源)的机制。CQ有n个完成队列实体(CQE)。CQE的数量在CQ创建的时候被指定。当一个CQP被轮询到,它就从CQ中被删除。CQ是一个CQE的先进选出(FIFO)队列。CQ能服务于发送队列、接收队列或者同时服务于这两种队列。多个不同QP中的工作请求(WQ)可联系到同一个CQ上。
4)内存注册(MR)
内存注册机制允许应用程序申请一些连续的虚拟内存空间或者连续的物理内存空间,将这些内存空间提供给网络适配器作为虚拟的连续缓冲区,缓冲区使用虚拟地址。内存注册进程锁定了内存页。(为了防止页被替换出去,同时保持物理和虚拟内存的映射)在注册期间,操作系统检查被注册块的许可。注册进程将虚拟地址与物理地址的映射表写入网络适配器。在注册内存时,对应内存区域的权限会被设定。权限包括本地写、远程读、远程写、原子操作、绑定。每个内存注册(MR)有一个远程的和一个本地的标志(r_key,l_key)。本地标志被本地的HCA 用来访问本地内存,例如在接收数据操作的期间。远程标志提供给远程HCA用来在RDMA操作期间允许远程进程访问本地的系统内存。同一内存缓冲区可以被多次注册(甚至设置不同的操作权限),并且每次注册都会生成不同的标志。
5)内存窗口(MW)
内存窗口使应用程序对来自远程的对本地的内存访问有更灵活的控制。内存窗口(MW)作用于以下应用场景:
• 想动态地授予和收回已注册缓冲区的远程访问权限,这种方式相比较与将缓冲区取消注册之后 再注册或者重注册,有些更低的性能损耗代价。
• 想为不同的远程代理授予不同的远程访问权限,或者在一个已注册的缓冲区中的不同范围内授予 那些权限。
内存窗口和内存注册之前的关联操作称为绑定。不同的MW可以作用于同一个MR(即使有着不同的访问权限)。
6)地址向量(Address Vector)
地址向量用来描述本地节点到远程节点的路由。在每个UC/RC的QP中,都有一个地址向量存在于QP的上下文中。在UD的QP中,每个提交的发送请求(SR)中都应该定义地址向量。
7)保护域(PD)
一种集合,它的内部元素只能与集合内部的其它元素相互作用。这些元素可以是AH,QP,MR和SRQ。保护域用来队列对(QP)与内存注册和内存窗口想关联,这是一种授权和管理网络适配器对主机系统 内存的访问。PD也用来将基于不可靠数据报(UD)的QP关联到地址处理(AH),这是一种对UD目的端的访问控制。
8)异步事件 网络适配器可能会发送异步事件来通知子网管理器(SW)系统中发生的事件。有两种异步事件:
附属事件:在私有对象(CQ,QP,SRQ)中发生的事件。这些事件会被发送到特定的进程。
非附属事件:在全局对象(网络适配器,端口错误)中发生的事件。这些事件会被发送到所有进程 。
9)散聚表(Scatter Gather List) 用分散聚合元素来分散和聚合数据。这些元素包括:地址:本地数据缓冲区的地址,缓冲区是数据聚合的终点或者是数据分散的源头。 大小:数据的大小会写到这个地址或者从这个地址读取。 L_key:注册到这个缓冲区的MR的本地标志。
10)轮询(Polling) 轮询CQ中的完成信息是为了获取已提交的WR(发送或者接收)的详细信息。如果我们在WR中发现一个异常状态的完成,接下来的完成都会异常(同时WQ会被移至错误状态)。每个没有完成(被轮询到)的WR都属于待处理状态。只有在WR完成之后,发送/接收缓冲区才可能被使用/再使用/释放。应该经常检测完成状态。当一个CQE被轮询,那么它就被从CQ中移除。轮询通过 ibv_poll_cq 操作来实现。
1) RDMA通信是完全异步的,而TCP/IP的原始socket通信是同步的,异步通信是借助额外框架(或扩展)实现的,如CSocket、WSASocket。
2) TCP/IP是一种面向字节流的传输方式 ,信息以字节的形式在套接字应用程序之间传递。而RDMA是基于消息式的。TCP/IP本身是不可靠的(传输过程中数据可能丢失或者失序),但是它利用传输控制协议(TCP)来实现可靠性机制。TCP/IP在所有操作中都需要操作系统的干预,包括网络两终端结点的缓冲区拷贝。在面向字节流的网络中,没有消息的边界概念。当一个应用想要发送一个数据包, 操作系统把这些字节数据放入内存中属于操作系统的一个匿名缓冲区,当数据传输完毕时,操作系统把它缓冲区中的数据拷贝到应用程序的接收缓冲区。这个过程在每个包到达时都会重复执行, 直到整个字节流被接收到。TCP负责将任何因拥塞导致的丢包进行重发。
在IB中,一个完整的消息被直接发送到一个应用程序。一旦一个应用程序请求了RDMA的读或写传输, IB的硬件将需要传输的数据按照需要分割成一些数据包,这些数据包的大小取决于网络路径的最大传输单元。这些数据包通过IB网络,被直接发送到接收程序的虚拟内存中,并在其中被组合为一个完整的消息。当整个消息都到达时,接收程序会接收到提示。这样,发送程序和接收程序在直到整个消息被发送到达接收程序的缓冲区之前都不会被打扰中断。
3) R DMA利用旁路和零拷贝技术提供了低延迟的特性,同时,减少了CPU占用,减少了内存带宽瓶颈,提供了很高的带宽利用率。这得益于RDMA消息服务呈现给应用的方式,和底层用来发送和传递这些消息的技术。RDMA提供了基于IO的通道。这种通道允许一个应用程序通过RDMA设备对远程的虚拟内存进行直接的读写。
在传统的socket网络中,应用程序要向操作系统申请使用网络资源时,要通过特定的API来管理程序的相关行为。但是,RDMA使用操作系统仅仅建设一个通道,然后就可以在不需要操作系统的干预下,应用程序之间就能够进行直接的消息传递。消息可以是RDMA读或写操作,也可以是发送/接收操作。
实验室现有平台:
处理器 |
Intel(R) Xeon(R) CPU E5-2650 (4 cores, 2.00GHz) |
操作系统 |
Ubuntu 12.04 |
PCI-e插槽 |
PCI-express 3.0 x8 |
内存 |
16GB DRAM |
IB设备类型 |
Mellanox MT27500 Family [ConnectX-3] |
ConnectX-3介绍
类型 |
CA(channel Aapter) |
传输速率 |
56 Gb/sec (4x FDR) |
链路层 |
infiniband |
注:FDR 十四倍速
测试性能
峰值带宽 |
6.1GB/s |
平均延迟 |
~4μs |
峰值消息速率 |
6 million msg/sec |
注:此测试在单线程情况下执行,测试了四种原语(send/recv、write、read),两种连接(RC、UD)。在多线程(每个主机2~4个线程)情况下,带宽会有一点点提高,约6.2 GB/s,但延迟会大幅提高,会较单线程高一个数量级,这也符合预期,多线程会带来上下文切换开销。
编程接口设计需要兼顾上层应用和底层通信原语。
上层应用直接调用通信原语,相对而言,调用路径更短,理论性能会更高。而且对于不同应用的特点可以调用不同的原语。但是对于大规模并发操作,需要一个管理程序做全局调度。当不同应用,各自为战,无法按照全局特性进行调度,比如在分布式文件系统的使用过程中,客户端同时产生了大量读请求和写请求,调用通信原语去远程服务器上读取、写入数据,这些请求会封装成WR,放到请求队列里,可能是无序的。事实上,在特定场景下,读请求应该比写请求优先级高,有了一个独立的请求重排、调度会更好。
同时,主机(包括客户端和服务器)需要有一个独立于应用的通信资源管理模块,比如面对大量连接的资源池(QP,类似于TCP/IP里的Socket)。首先需要实现一个连接管理的通信框架,支持多线程调度、多QP传输、以及大量RDMA传输相关资源(如QP、CQ、channel等)的管理,包括但不限于以上功能。由于RDMA传输是异步的,不需要像同步的socket编程那样自己来实现一个异步通信框架,来提高性能。
在应用负载低的情况下,更短的协议路径更有效,但面大规模负载,分层设计会逐层减轻位于下层的模块的压力,同时也方便进行隔离与解耦,这时扁平化的设计不一定能带来最佳效果,当然,这也需要后续测试来根据不同应用场景做决定。
另一方面,由于RDMA传输特点鲜明,one-sided RDMA和two-sided RDMA各有特点,另外,还有atomic原语。比如,在面对高并发场景时,在需要确保操作是线程安全的(特别是,在多生产者的环境下,更新下一个可用的序列号)场景,我们可以使用atomic原语(Compare And Swap/Set), 它的工作方式有点像乐观锁——CPU去更新一个值,但如果想改的值不再是原来的值,操作就失败,因为很明显,有其它操作先改变了这个值。这个原语可以简化我们的操作,如果按照传统的为保证线程安全,先获取锁,再更新值,至少会有两次RDMA操作(获取锁并确认,一个round trip;进行修改操作并确认,一个round trip;算释放锁的话还要再加一次)。
在读取数据时,选用RDMA read更好,性能更高,但不可避免地遇到读写竞争,导致客户端读到的服务器端的数据是不正确的。也可以采用增加自验证数据结构的方式,增加对数据的校验(指纹)。读的时候采取乐观锁的方式,即先用RDMA read读取数据(包含校验),然后等拉取过来之后算校验,如果校验不符,说明远端有读写竞争,数据不合法,所以将这个数据直接丢弃,过一段时间后重新取数据。如果校验正确的话,就只有一次RDMA read 操作,延迟低很多。
所以,通信原语的选择应该对应用(上层接口)开放,以便根据情况来选择最合适的。
RPC 实现了对基础通信原语的封装,更具有通用性和可移植性。RPC框架包括基本的通讯组件、协议编解码组件(序列化和反序列化网络传输的数据,主要用于跨语言支持)、服务注册调用组件等。
RPC具有的特点有
基于RDMA实现的RPC在面对大规模分布式应用时,其多增加的一层RPC处理层(相对于应用直接用RDMA)的开销并相对于其他瓶颈开销并不大,大规模并发操作的关键瓶颈有锁、上下文切换等。当然,最后需要测试结果来说明。
RPC还可以在服务级提供调度功能。比如读一个文件是一个服务,它由多个通讯请求组成(发到不同的服务器上,请求不同的块)。如果相同的读请求,直接在服务层做请求合并,而不是等到在通讯层发现发送两个相同的请求到同一个远程服务器,在通讯请求层做服务合并和调度。RPC层可以增加一个调度粒度,避免了通讯请求层粒度细,给通讯调度层带来压力。
总结,综上所述,现在的编程接口设计层次如下:
上层应用接口 |
RPC(可选) |
连接与资源管理、调度模块 |
RDMA通讯原语 |
其中,RDMA通讯原语层实现五种不同的原语和三种传输类型的C/S或者request-reply的通讯;连接与资源管理、调度模块负责QP连接和资源分配、调度、管理和释放等工作,还有包括请求合并等功能。RPC做服务级管理和调度,由于使用这一层的必要性没有实验数据的论证,暂时不必要添加。最上层就是面对应用接口和业务逻辑。
术语对照表
术语 |
释义 |
Access Layer |
操作系统底层构架,用来支持访问互联的集群(VPI,InfiniBand,Ethernet,FCoE). 它包括所有支持上层网络协议的基本传输服务、中间件和管理程序 |
AH(Address Handle) |
在UD QP中,用来描述远程路径的对象 |
CA(Channel Adapter) |
一个InfiniBand链路的终端设备,它执行传输层的功能 |
CI(Channel Interface) |
通过网络适配器、相关固件和设备驱动的组合,呈现给Verbs 编程用户的通信管道 |
CM(Communication Manager) |
负责建立、维持、释放RC和UC QP服务类型连接的体系;服务ID解析协议 确保了使用UD服务的用户找到支持指定设备的QP;每个终端节点的IB端口都有一个CM. |
Compare & Swap |
通知远程QP读取一个64bit的值,将这个值与提供的比较对象值作比较 ,如果相等,那么就把读取的这个值替换成QP提供的另一个数值。 |
CQ(Completion Queue) |
一个包含CQE的队列(先进选出) |
CQE(Completion Queue Entry) |
CQ中的一个记录,它描述了已完成的WR的信息 (状态,大小等) |
DMA(Direct Memory Access) |
允许硬件在不经CPU参与的情况下 将数据块移进和移出内存 |
Fetch & add |
通知远程QP读取一个64bit的数值,将它替换为它和QP提供 的待加数的和。 |
GUID(Globally Unique IDentifier) |
在一个子网中,唯一标志一个设备或组件的 64bit数字 |
GID(Global IDentifier) |
一个128位的标志,用来标志网络适配器上的一个端口, 路由器上或者组播里的一个端口;为了更有效地寻找、通信和路由,IBA在标准IPV6地址的基础上定义了一些额外的 特性和约束,这就形成了GID。 |
GRH(Global Routing Header) |
用来在子网间传递数据包和传递组播信息的包头。 包头基于IPv6协议 |
Network Adapter |
允许网络中计算机之间传递数据的硬件。 |
Host |
一台运行着操作系统,并且控制着一个或多个network adapter的计算机。 |
IB |
InfiniBand |
Join operation |
一个IB端口要明确地加入一个多播组,必须向SA发送请求来接收 多播数据包。 |
lkey |
在MR注册之后接收到的一个数字,它在本地被WR用来标志内存注册和 相关权限。 |
LID(Local IDentifier) |
子网管理程序指定给终端节点的一个16位地址。每个LID在它所在的子网中是唯一的。 |
LLE(Low Latency Ethernet) |
在CEE(Converged Enhanced Ethernet聚合加强型以太网)基础之上的RDMA服务。CEE允许IB在以太网上传输。 |
NA(Network Adapter) |
一个网络链接的终端设备,它执行传输层功能。 |
MGID(Multicast Group ID) |
MGID唯一标志一个IB多播组,它由SM管理。SM将每个MGID都关联一个MLID,并对网络中的IB交换机 进行编程控制,确保加入多播组的所有端口都能接收到数据包。 |
MR(Memory Region) |
已被注册为被允许使用的连续内存缓冲区。为了使网络适配器能利用它们,这些缓冲区需要先被 注册。在注册期间,一个L_Key和R_Key被创建出来用来关联相应的注册缓冲区。 |
MTU(Maximum Transfer Unit) |
端口收发数据包的最大有效负载的数据大小(不包括包头)限度。 |
MW(Memory Window) |
一个被分配的资源,在与已注册的内存中一块特定的区域绑定后,能被远程直接使用。每个MW都有一个 关联的窗口句柄、一些使用权限信息和当前的R_Key |
Outstanding Work Request |
工作队列中没有被轮询到已完成的WR |
pkey(Partition key) |
pkey标志了端口所属的分区。pkey大概类似于以太网中的VLAN ID。pkey用来指向端口的 pkey表中的一项。SM(subnet manager)将每个端口至少关联一个pkey |
PD(Protection Domain) |
只有内部成员才能进行交互的域。AH与QP进行交互,MR与WQ进行交互。 |
QP(Queue Pair) |
为了在网络中节点之间传递数据,将独立的WQ打包在一起形成的一个配对 (发送队列和接收队列)。有三种类型的QP:UD 不可靠数据报,UC 不可靠连接,RC 可靠连接。 |
RC(Reliable Connection) |
基于面向连连接的QP传输服务。一个QP与另一个QP相关联,两者之间的信息传输是可靠的 (具体体现在数据的正确性和顺序性) |
RDMA(Remote Direct Memory Access) |
在不需远程计算机CPU的干预下,对它的内存进行操作。 |
RDMA_CM(Remote Direct Memory Access Communication Manager) |
用来建立可靠性连接和不可靠性数据报传输的API。它为建立连接提供了RDMA传输接口。 此API基于套接字,同时又适用于基于QP的语义:信息传递必须通过专门的RDMA设备, 并且数据传输是基于消息机制。 |
Requestor |
在一个连接中,发起数据传输的一端(通过发送一个请求) |
Responder |
在一个连接中,回复发起者发送的请求命令的的一端。请求命令可能包括 对回复者内存进行读或写的请求,和要求回复者接收一条信息。 |
rkey |
在MR注册之后接收到的一个数字,对到来的RDMA操作进行许可认证。 |
RNR(Receiver Not Ready) |
在一个基于RC的QP中,两端的连接已经存在,但是RR目前不在接收端。 |
RQ(Receive Queue) |
一个用来存储用户发送的RR的工作队列。 |
RR(Receive Request) |
是一个会被发送到RQ中的WR。它描述了应该把到来的需要写的数据写在哪里。 需要注意的是,一个RDMA写操作会消耗一个RR。 |
RTR(Ready To Receive) |
一种QP的状态,它表示某个RR可以被发送和处理。 |
RTS(Ready To Send) |
一种QP的状态,它表示某个SR可以被发送和处理。 |
SA(Subnet Administrator) |
用来查询和操作子网管理数据的接口。 |
SGE(Scatter/Gather Elements) |
一个结构,指向本地已注册过的内存块的一部分或者整块。结构中的元素包含 内存块的起始地址、大小和lkey(和它相关的权限信息一起)。 |
S/G Array |
在WR里,存放S/G元素的元组。根据使用的操作命令,可以将不同缓冲区的数据收集起来, 并将这些数据当成一个单独的数据流进行发送,或者将一个单独的数据流切分成许多不同的 缓冲区。 |
SM(Subnet Manager) |
设置和管理子网的体系。它的功能包括:获知子网的网络拓扑结构,分配LID, 决定路由策略和设置路由表,一个主的SM或者还有一个从的SM(双机热备模式), 初始化子网中交换机的路由表从而在子网中建立网络通路。 |
SQ(Send Queue) |
用来存储用户发送的SR的队列。 |
SR(Send Request) |
是一个会被发送到SQ中的WR,描述了需要传输的数据有多大、数据的目标位置以及传输的方式 (具体的操作码会确定传输方式)。 |
SRQ(Share Receive Queue) |
是一个保存着接收到的信息的WQE队列,接收到的信息可以来自于任何相关的RC/UC/UD QP. 多个QP可与同一个SRQ关联。 |
TCA(Target Channel Adapter) |
一个不需要支持verb语法的通道适配器,通常用在I/O设备中。 |
UC(Unreliable Connection) |
基于面向连接的QP传输服务,一个QP和另一个QP相联系。QP们没有执行可靠协议,传输过程中 信息可能丢失。 |
UD(Unreliable Connection) |
一种QP传输服务,消息的以包为单位。每个UD QP能和子网中其它的UD QP进行数据的接收和发送。 消息在传递的过程中可能会丢失并且到达顺序可能会混乱。UD QP是唯一支持多播消息的模式。 UD数据包的大小受限于MTU |
Verbs |
网络适配器的功能的一种抽象描述。使用Verbs,任何应用都能创建和管理用于RDMA数据传输的 对象。 |
VPI(Virtual Protocol Interface) |
允许用户能够改变端口的2层协议。 |
WQ(Work Queue) |
SQ或RQ中的一种。 |
WQE(Work Queue Element) |
WQ(工作队列)中的一个元素。 |
WR(Work Request) |
用户提交至WQ(工作队列)的一个请求。 |