



























Although NIC could upload local states in host memory, swapping data between on-chip memory and host memory has a cost and frequent swapping would significantly downgrades performance [32, 33] (also see §2.3). As a consequence, the key design goal for a multi-path RDMA transport is to minimize the memory footprint
NIC与主机交换内存是会引入一定开销的,因此做设计要尽量减小内存占用。
MP-RDMA要关注的两大问题在于多路径和RDMA本身对于乱序的敏感。主要是三个问题:
如果引入了NIC与主机通过PCIe总线的内存交换,吞吐就会急剧下降,如论文图2所示:

MP-RDMA直接对ACK做出反应:
如果一个ACK的ECN位被标记,则窗口减小半个段(而不是减半),如果ECN没有被标记,则窗口增加1/cwnd
MP-RDMA要求每个包都要ACK,引入约 4% 的额外带宽开销
MP-RDMA维护一个 inflate 变量,每收到一个 ACK 该变量就增加 1。我们使用 snd_nxt 表示已发送的最高数据包的 PSN,使用 snd_una 表示已累积确认的最高数据包的 PSN。那么可用窗口 (awnd) 为:awnd = cwnd + inflate - (snd_nxt - snd_una)
一旦 ACK 移动了 snd_una,inflate 就会减少 (ack_aack - snd_una)
MP-RDMA在网卡上用长度为固定长度的循环数组作为位图跟踪包的状态,每个包占用2bit,也就是说有4种状态:
接收端持续从队头消息开始扫描位图,如果在tail/tail with completion 前一直都是received,说明这条消息已经收完,此时将这些slot全部设为empty,然后移动队头消息指针。
MP-RDMA可以允许的乱序程度受网卡内存以及位图大小限制,所以需要停用一些慢的路径以避免乱序到达。
为了识别出这些慢路径,我们首先需要知道MP-RDMA是如何表示路径的。MP-RDMA复用了UDP包头的字段,将“源端口”字段解释为VP(虚拟路径)。中间设备也根据VP路由。所以无论是发送的数据包还是ack,都是带有路径标识的。
MP-RDMA采用了一个容忍窗口的方法:

snd_ooh是被ack确认的最高的包编号,delta是人为设定的,那么snd_ool就相当于是可容忍的最慢的包,如果ack确认了一个编号比snd_ool还低的包,说明它的VP是慢路径,这个路径的cwnd要减1, 并且这个ack不会让新的包发送,这样可以实现流量逐步迁移到更快的路径。
RDMA有个单边写入的Write操作,允许发送端直接写接收端的内存。(RDMA这块我感觉后面要读读《RDMA杂谈》来补补基础知识)
但是这个写操作所涉及的数据包不总是按顺序到达,然而部分情况下我们又要求写入顺序不能乱。
为了解决这个问题,一种朴素的想法是在host内存里开辟缓存区,将所有数据都收好再写入,但是这样显然会引入NIC和host之间反复通信的延迟和带宽,不是一个优雅的解决方案。
MP-RDMA于是仍然会默认直接写入内存
对于需要确保同步的操作,在其包头打上synchronise标签。这会确保这个操作之前的操作都已经结束。
如果等待所有之前的包都被ACK确认再发送同步包,会浪费一整个RTT,因为需要一直等到最后一个包发出,最后一个包的ACK收到。此时就已经没有在途数据包了,这是带宽的浪费。
MP-RDMA的思想应该是在于不等ack回来了,自己算出来最后一个包什么时候能到。
最理想的情况下,同步包可以紧挨着最后一个包进行发送,这是建立在所有数据包按序到达的假设之上的,但是现实是可能存在乱序。
不过在“慢路径剪枝”中我们已经知道了MP-RDMA会尽量将乱序控制在delta以内。那么所有乱序处理完成的时间可以估算为安全系数*delta/发送速率,那么将同步包延后这样一段时间发送基本就可以实现按序到达。
当然,乱序程度有时也会大于delta,这种情况下,同步包会先于前面的包到达,接收端会直接丢弃并发送NACK,指示发送端重新发送。
在正常情况下,该算法将 OOD 控制在
delta左右。然而,如果数据包丢失,OOD 将持续增加,直到超过跟踪位图的大小。然后,接收端将生成一个 NACK,以通知丢失数据包的 PSN。收到 NACK 后,MP-RDMA 进入恢复模式。具体而言,我们将当前的snd_nxt值存储到一个名为recovery的变量中,并将snd_retx设置为被 NACK 的 PSN(图 7)。在恢复模式下,传入的 ACK 会时钟触发由snd_retx指示的重传数据包,而不是新数据包。如果snd_una移动超过了recovery,则丢包恢复模式结束。这里有一个微妙的问题。由于 MP-RDMA 仅在位图溢出时进入恢复模式,如果应用程序没有那么多数据要发送,则会触发重传超时 (RTO)。为了避免这种 RTO,我们采用了 FUSO 的方案,即如果没有新数据可传输且 awnd 允许,则作为新数据早期重传未确认的数据包。在重传也丢失的罕见情况下,RTO 最终会触发,发送端将开始重传所有未确认的数据包。
以上梳理来自Qwen-3.8-Max-Preview
每个RTT内有一定概率生成随机VP的包发出,以探索路径
其实我感觉这方面考虑到了还是很细致的。MP-RDMA的作者认为有时候ack回来会导致发送端发出多个包导致那条VP拥塞。解决方案是限制一个ACK最多会让2个包发出去。如果等不来ACK,在半个RTT后(去向链路上已经没有包),再随机喷洒到一些VP上。
如果路径不活跃了,就也不会有ACK了,有可能在一段时间内窗口都得不到更新,那么当这个VP下一次要承载数据的时候,当前的窗口大小可能已经不适用了。为了防止下一次发送时过大的窗口直接把带宽撑爆,当发送端没有数据可发时,收到ACK只会让窗口大小-1
我感觉和上一条是类似的,如果一个连接空闲了一段时间(比如 3 个 RTT),重新开始传输 时,必须回到初始窗口。
这块应该就是在说MP-RDMA能和PFC配合工作
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。