【RDMA】IBV_SEND_INLINE和IBV_SEND_SIGNALED的原理|RDMA小消息通信性能优化
目录
原理
IBV_SEND_INLINE和IBV_SEND_SIGNALED 是RDMA 优化小消息通信性能的收到之一。
其原理是:
IBV_SEND_INLINE 减少网卡的DMA。(CPU直接将数据写入网卡缓冲,而不是等网卡来DMA)
IBV_SEND_SIGNALED 减少WC的产生和对WC的读取次数。
说白了,就是网卡驱动注册了一块MEM内存,用户程序post WQ的时候往里面写如WQE,如果要发送的数据大,数据放在用户空间的buff,那么WQE里面的指针指向buff。网卡从MEM里面读出WQE,然后根据WQE里面 指针,再去buff读取数据。如果要发送的数据小,就直接把数据放到WQE的paylod区域,一同放入MEM内存。这样网卡从MEM里面读出WQE,就不在需要再去buff读取数据。
原理详细说明见:
【RDMA】InfiniBand如何工作和小消息通信性能优化方案_bandaoyu的note-CSDN博客
IBV_SEND_SIGNALED
- unsigned Completions:IB默认是为每个WQE发送一个完成信号,但IB也允许应用程序关闭指定的WQE的完成(信号),但是注意每隔post n 个关闭信号的WQE,就要post一个开启完成信号的WQE 。(因为只有产生CQE,程序去读取了CQE之后才会清理发送队列SQ的SQE,如果一直没有CQE产生,则读取不断CQE也不就不会清理发送队列SQ,很快发送队列SQ就会撑满)
关闭Completion可以减少NIC对CQE的DMA writes。此外,应用程序轮询更少的CQE,从而减少了开销。
关于无信号完成的详细说明:【RDMA】使用‘无信号完成’(Working with Unsignaled completions)|IBV_SEND_SIGNALED_bandaoyu的note-CSDN博客_rdma网卡
深层原理:【RDMA】InfiniBand如何工作和小消息通信性能优化方案_bandaoyu的note-CSDN博客
IBV_SEND_INLINE
原理:【RDMA】InfiniBand如何工作和小消息通信性能优化方案_bandaoyu的note-CSDN博客
IBV_SEND_INLINE -sg_list中指定的内存缓冲区将内联放置在SR( WQE)中。这意味着底层驱动程序(即CPU)将读取数据,而不是RDMA设备。这意味着将不会检查L_Key,实际上那些内存缓冲区甚至不必注册(毕竟CPU本来是老大/主子),并且可以在ibv_post_send()将要结束后,立即重用它们。仅对Send和RDMA write操作码有效。
由于在该代码中没有涉及到key的交换,所以也无法使用RDMA传输,所以还是使用了CPU读取数据,既然是CPU读取,那么也就不需要注册内存缓冲区了,这个标记只能用于Send和RDMA write操作。
The flag IBV_SEND_INLINE describe to the low level driver how the data
will be read from the memory buffer
(the driver will read the data and give it to the HCA or the HCA will
fetch the data from the memory using
the gather list).
The data on the wire for inline messages looks the same like data which
was fetched by the HCA.
The receive side don't have any feature which can work with memory
buffer without any registration.
-sg_list中指定的内存缓冲区将内联放置在SR( WQE)中。(即原先是SR(内含sg_list)和sg_list中指向的内存缓冲区 放置在两个位置,网卡先读取SR获得sg_list,再根据sg_list信息读取sg_list指向的内存缓存。需要两次DMA操作。内联就是将内存缓存区放置在SR内,网卡读取SR就一并获得内存缓存,只需一次DMA)
带来的好处:
不使用INLINE:
data 标记到sg_list,post 一个WR, RDMA到WR 队列获取WR,然后读取sg_list中的数据到RDMA网卡发送缓冲。
使用INLINE:
这个不太好理解,从下面描述mellonx如何实现这个功能的这段文字:
“if IBV_SEND_INLINE is set, the code memcpys the data into the descriptor and does not keep any reference to the pointers passed in through the sg ilst.”
(https://www.spinics.net/lists/linux-rdma/msg26693.html)
我个人理解是:
一旦IBV_SEND_INLINE被设置,在执行post的时候CPU不是把SR放到SQ上等着网卡来dma,而是CPU直接将SR中的指向的数据直接写到网卡的描述符(descriptor)中,即直接写入网卡缓冲。写完就完成了SR指向的内存到网卡缓存的数据转移,SR指向的内存就可以释放或重新利用了。
省去了RDMA网卡到WR 队列获取WR的过程,减少了时延。
使用INLINE的陷阱
根据文档, inline发送不需要等待wc就可以重用发送buffer. 不需要等待wc就可以继续发消息,但是如果不处理wc,那么就不会清理sr,连续不断的继续发送INLINE消息(而不去处理wc),sr得不到清理最终会撑爆sq,导致最后发不出消息。
所以使用INLINE的时候记得在sq撑爆之前去处理wc。
案例:《ibv_post_send() work queue overflow》ibv_post_send() work queue overflow - 知乎
@UESTC