From 11a217bf8a7fc87cfb4ba2396ba351a7f8d8e176 Mon Sep 17 00:00:00 2001 From: zzs Date: Wed, 10 Sep 2025 16:15:48 +0800 Subject: [PATCH 1/5] issue8 --- src/code/issue8/AllToAll.md | 150 ++++++++++++++++++ .../communication-bottlenecks-cpu-proxy-b.png | Bin 0 -> 61629 bytes .../images/ibgda-direct-control-path-b.png | Bin 0 -> 65445 bytes 3 files changed, 150 insertions(+) create mode 100644 src/code/issue8/AllToAll.md create mode 100644 src/code/issue8/AllToAll/images/communication-bottlenecks-cpu-proxy-b.png create mode 100644 src/code/issue8/AllToAll/images/ibgda-direct-control-path-b.png diff --git a/src/code/issue8/AllToAll.md b/src/code/issue8/AllToAll.md new file mode 100644 index 0000000..59f66a6 --- /dev/null +++ b/src/code/issue8/AllToAll.md @@ -0,0 +1,150 @@ +为了计算NVSHMEM基于IBRC和IBGDA的AllToAll集合通信的理论耗时,采用LogGP模型来进行分析。 + +# LogGP模型简介 + +LogGP的五个参数: + +- L(Latency):通信延迟,表示从消息发送到消息接收所需的时间 +- o(Overhead):在发送端和接收端处理消息时产生的开销 +- g(Gap):消息之间的最小时间间隔,反映网络的带宽限制 +- G(Gap per byte):表示每个字节传输的时间开销,用来描述大消息的传输情况 +- P(Processors):处理器的数量 +- n 是消息的总大小(字节数) + +LogGP模型的通信延迟公式为: +$$ +T=L+2\times{o}+\frac{n}{G} +$$ + +# NVSHMEM的AllToAll Kernel + +本次分析主要聚焦于IBGDA和IBRC,因此对AllToAll中有关NvLink、P2P等相关的优化暂时忽略。 + +`nvshmemi_call_alltoall_on_stream_kernel`在launch Kernel时,设置num_blocks为1,因此AllToAll Kernel只有一个Block,在一个SM上执行。 + +``` +alltoall_on_stream_kernel<<>>( + team, dest, source, nelems, in_cuda_graph); +``` + +`nvshmemi_alltoall_allpush_threadgroup`在执行时,通过for循环,使得Block中的每一个thread都负责将对集合通信中的其他PE执行PUT操作。最终确保了所有PE之间AllToAll的成功实现。该函数的每一个thread会调用: + +```c++ +nvshmemi_transfer_put_signal +``` + +在启用IBGDA时,该函数内部调用`nvshmemi_ibgda_put_signal`,否则使用IBRC,调用`nvshmemi_proxy_rma_nbi`。 + +对于`nvshmemi_ibgda_put_signal`而言,其内部包括Thread和WARP/BLOCK两种实现方法,不过在该Kernel下,指定了其采用Thread的方法,即`nvshmemi_ibgda_put_signal_thread_impl`。 + +**两者的核心差异:** + +**IBRC**:GPU将通信请求放入指令队列,由一个单线程的CPU Proxy负责读取、解析指令,并最终利用指令中的信息调用网络库完成通信。 + +**IBGDA**:GPU Kernel自己构造WQE,并通过内存映射直接将WQE发送到网卡的指令队列,中间完全绕过了CPU。 + +# IBRC + +![img](AllToAll/images/communication-bottlenecks-cpu-proxy-b.png) + +在IBRC中,最终与网络驱动交互、发起通信的处理器是CPU,其利用CPU Proxy不断处理GPU发来的传输指令。因此,对于IBRC来说: + +- L:不变,由物理网络决定 +- o:开销很大,包括了GPU写指令、CPU代理读取并解析指令、调用网络库函数、CPU代理轮询完成队列、处理完成事件、更新状态等 +- G:由网络物理带宽决定 + +AllToAll操作需要每个PE向其他P-1个PE发送消息,每次传输的数据总大小为n。由于CPU代理的串行瓶颈,它必须一个接一个处理P-1个发送请求。 +$$ +T_{alltoall\_IBRC} \approx L+2\times o_{IBRC}+\frac{M}{G} +$$ +其中, +$$ +M=(P-1) \times n +$$ + +## IBRC各步骤耗时 + +1. GPU端进行指令的生成与提交($T_{GPU}$) + + GPU Kernel中transfer_dma所做的工作,包括: + + - 通过atomicAdd在环形队列中预留空间 + - 执行check_channel_availability进行流控,请求过多时可能会导致等待 + - 利用位运算,将PUT操作的详细信息(如远程地址的roffset、操作类型、group_size、标志位flag、laddr、size等),注意构建了4个8字节的指令包 + - 通过volatile 64位内存写入,将指令包传给环形队列 + + 该部分耗时主要在GPU上的原子操作、内存读写以及可能的自旋等待组成,在环形队列未满时,耗时较短且相对固定。 + $$ + T_{GPU}=T_{atomicAdd}+T_{flow\_control}+T_{build\_packets} + $$ + +2. GPU与CPU的切换,包括通信延迟与唤醒延迟($T_{sync\_wakeup}$) + + - GPU需要通过__threadfence()确保其写入的指令对CPU可见,且GPU需要通过PCIE向主机内存中写入指令 + - 内核调度器唤醒CPU Proxy,涉及到一次上下文切换 + + $$ + T_{sync\_wakeup}=T_{GPU\_fence}+T_{PCIE}+T_{os\_shedule} + $$ + +3. CPU端指令处理($T_{CPU\_proxy}$) + + CPU Proxy中process_channel_dma函数所做的工作 + + - 读取并等待上面四个指令,其中会用到__sync_synchronize()这个内存栅栏,有较大的时间开销。在这一阶段能够重组获得laddr、size、pe、op、rptr + - 之后提交传输操作,通过nvshmemi_process_multisend_rma执行具体的网络传输 + + 该部分耗时主要是同步开销。 + $$ + T_{CPU\_proxy}=T_{spin\_wait}+T_{CPU\_{fence}} + $$ + +4. 网络传输($T_{Network}$) + + 这部分由`nvshmemi_process_multisend_rma` 函数及其调用的底层网络库(如 `libibverbs`)所做的工作。 + + - 进行内存注册,获取内存密钥lkey/rkey + - 根据数据大小决定是否进行数据分块 + - 调用网络库API,由库函数创建WQE + - Ringing the Doorbell,启动DMA传输 + + 该部分即LogGP的主体部分 + $$ + T_{Network}=T_{lib}+L+\frac{M}{G} + $$ + 其中$T_{lib}$是调用网络库函数的开销 + +因此,对于小消息而言,其总延迟有很大程度上受到前三个阶段的影响,特别是CPU Proxy对于指令的串行执行与上下文切换,导致其瓶颈主要在CPU端,带宽难以充分利用。而大消息因其单次指令传输数据大,主要瓶颈在带宽方面,故其对带宽的利用率较高,与IBGDA类似。 + +# IBGDA + +![img](AllToAll/images/ibgda-direct-control-path-b.png) + +基于IBGDA的AllToAll Kernel在实现上调用`nvshmemi_ibgda_put_signal_thread_impl`,该方法依据NVSHMEMI_THREADGROUP_THREAD级别进行指令的发送。 + +## Thread + +1. 该线程独自调用ibgda_get_qp()获取与目标PE通信的QP,调用ibgda_get_lkey/ibgda_raddr_rkey获取本地和远程内存的内存密钥,并确定这些密钥能覆盖的最大数据范围 +2. 根据传输的数据量和密钥的覆盖范围,决定是采取方案1还是方案2。 + - 方案1:当全部数据可以一次性完整传输时,调用ibgda_reserve_wqe_slots在网卡命令队列中预留所需的所有WQE槽位,并依次写入PUT和Signal的WQE,最后调用ibgda_submit_requests通知网卡开始工作。 + - 方案2:当数据总量超过了单次传输上限时,对数据进行分块,通过循环,按照“获取当前块密钥、预留WQE、写入WQE、提交”的顺序执行,直到将所有数据块都传输完毕。 +3. 如果不是非阻塞式的,则调用ibgda_quiet,等待网卡确认所有任务完成,GPU不断轮询CQ来判断传输是否完成。 + +在IBGDA中,发起通信的处理器是GPU,由其SM直接向NIC发送指令。 + +- L:不变,由物理网络决定 +- o:比较低,发送开销仅包括GPU构造几条指令来构建WQE,并”按响门铃“(一次MMIO写操作)的时间。 +- G:同样由网络物理带宽决定 + +$$ +T_{alltoall\_IBGDA} \approx L+2\times o_{IBGDA}+\frac{M}{G} +$$ + +其中, +$$ +M=(P-1) \times n +$$ + +## IBGDA各步骤耗时 + +IBRC在执行传输时,GPU需要向CPU Proxy发送特定地指令,让CPU Proxy解析指令获得构造wqe的信息。而IBGDA跳过了这一系列步骤,由GPU直接生成wqe,并将其写入网卡。由于GPU是SIMT的编程模型,单个warp内的多个thread可以同时向网卡写入wqe,因此避免了小消息时,带宽利用不充分的问题。 diff --git a/src/code/issue8/AllToAll/images/communication-bottlenecks-cpu-proxy-b.png b/src/code/issue8/AllToAll/images/communication-bottlenecks-cpu-proxy-b.png new file mode 100644 index 0000000000000000000000000000000000000000..f7a9c9a3bb9579654f0d5bbf8b8801ce39c7ee9f GIT binary patch literal 61629 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 literal 0 HcmV?d00001 diff --git a/src/code/issue8/AllToAll/images/ibgda-direct-control-path-b.png b/src/code/issue8/AllToAll/images/ibgda-direct-control-path-b.png new file mode 100644 index 0000000000000000000000000000000000000000..5ecd8a5f509f28ac3de701f3e36a70ae636218a3 GIT binary patch literal 65445 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 Date: Wed, 10 Sep 2025 16:25:43 +0800 Subject: [PATCH 2/5] issue8 --- src/code/issue8/AllToAll.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/code/issue8/AllToAll.md b/src/code/issue8/AllToAll.md index 59f66a6..18efa60 100644 --- a/src/code/issue8/AllToAll.md +++ b/src/code/issue8/AllToAll.md @@ -12,10 +12,14 @@ LogGP的五个参数: - n 是消息的总大小(字节数) LogGP模型的通信延迟公式为: + + $$ T=L+2\times{o}+\frac{n}{G} $$ + + # NVSHMEM的AllToAll Kernel 本次分析主要聚焦于IBGDA和IBRC,因此对AllToAll中有关NvLink、P2P等相关的优化暂时忽略。 @@ -64,7 +68,7 @@ $$ ## IBRC各步骤耗时 -1. GPU端进行指令的生成与提交($T_{GPU}$) +1. GPU端进行指令的生成与提交(\(T_{GPU}\() GPU Kernel中transfer_dma所做的工作,包括: From 20094833c9c6101f5bb8dfbebb5f9ec6dc2ea9cf Mon Sep 17 00:00:00 2001 From: zzs Date: Wed, 10 Sep 2025 17:16:31 +0800 Subject: [PATCH 3/5] issue8 --- src/code/issue8/AllToAll.md | 42 ++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/src/code/issue8/AllToAll.md b/src/code/issue8/AllToAll.md index 18efa60..6db9ca0 100644 --- a/src/code/issue8/AllToAll.md +++ b/src/code/issue8/AllToAll.md @@ -58,14 +58,22 @@ nvshmemi_transfer_put_signal - G:由网络物理带宽决定 AllToAll操作需要每个PE向其他P-1个PE发送消息,每次传输的数据总大小为n。由于CPU代理的串行瓶颈,它必须一个接一个处理P-1个发送请求。 + + $$ -T_{alltoall\_IBRC} \approx L+2\times o_{IBRC}+\frac{M}{G} +T_{IBRC} \approx L+2\times o_{IBRC}+\frac{M}{G} $$ + + 其中, + + $$ M=(P-1) \times n $$ + + ## IBRC各步骤耗时 1. GPU端进行指令的生成与提交(\(T_{GPU}\() @@ -78,20 +86,25 @@ $$ - 通过volatile 64位内存写入,将指令包传给环形队列 该部分耗时主要在GPU上的原子操作、内存读写以及可能的自旋等待组成,在环形队列未满时,耗时较短且相对固定。 + + $$ - T_{GPU}=T_{atomicAdd}+T_{flow\_control}+T_{build\_packets} + T_{GPU}=T_{atomicAdd}+T_{flowControl}+T_{buildPackets} $$ -2. GPU与CPU的切换,包括通信延迟与唤醒延迟($T_{sync\_wakeup}$) + +2. GPU与CPU的切换,包括通信延迟与唤醒延迟($T_{syncWakeup}$) - GPU需要通过__threadfence()确保其写入的指令对CPU可见,且GPU需要通过PCIE向主机内存中写入指令 - 内核调度器唤醒CPU Proxy,涉及到一次上下文切换 + $$ - T_{sync\_wakeup}=T_{GPU\_fence}+T_{PCIE}+T_{os\_shedule} + T_{syncWakeup}=T_{GPUFence}+T_{PCIe}+T_{shedule} $$ + -3. CPU端指令处理($T_{CPU\_proxy}$) +3. CPU端指令处理($T_{CPUproxy}$) CPU Proxy中process_channel_dma函数所做的工作 @@ -99,9 +112,12 @@ $$ - 之后提交传输操作,通过nvshmemi_process_multisend_rma执行具体的网络传输 该部分耗时主要是同步开销。 + + $$ - T_{CPU\_proxy}=T_{spin\_wait}+T_{CPU\_{fence}} + T_{CPUproxy}=T_{spinWait}+T_{CPUfence} $$ + 4. 网络传输($T_{Network}$) @@ -113,9 +129,13 @@ $$ - Ringing the Doorbell,启动DMA传输 该部分即LogGP的主体部分 + + $$ T_{Network}=T_{lib}+L+\frac{M}{G} $$ + + 其中$T_{lib}$是调用网络库函数的开销 因此,对于小消息而言,其总延迟有很大程度上受到前三个阶段的影响,特别是CPU Proxy对于指令的串行执行与上下文切换,导致其瓶颈主要在CPU端,带宽难以充分利用。而大消息因其单次指令传输数据大,主要瓶颈在带宽方面,故其对带宽的利用率较高,与IBGDA类似。 @@ -137,14 +157,22 @@ $$ 在IBGDA中,发起通信的处理器是GPU,由其SM直接向NIC发送指令。 - L:不变,由物理网络决定 + - o:比较低,发送开销仅包括GPU构造几条指令来构建WQE,并”按响门铃“(一次MMIO写操作)的时间。 + - G:同样由网络物理带宽决定 + + $$ -T_{alltoall\_IBGDA} \approx L+2\times o_{IBGDA}+\frac{M}{G} +T_{IBGDA} \approx L+2\times o_{IBGDA}+\frac{M}{G} $$ + + 其中, + + $$ M=(P-1) \times n $$ From 1770569d11e2109a7cf9e8699395fc4907ec745f Mon Sep 17 00:00:00 2001 From: zzs Date: Wed, 10 Sep 2025 22:21:05 +0800 Subject: [PATCH 4/5] issue8 --- src/code/issue8/AllToAll.md | 111 ++++++++++++++++++++---------------- 1 file changed, 62 insertions(+), 49 deletions(-) diff --git a/src/code/issue8/AllToAll.md b/src/code/issue8/AllToAll.md index 6db9ca0..70f0b5c 100644 --- a/src/code/issue8/AllToAll.md +++ b/src/code/issue8/AllToAll.md @@ -14,6 +14,7 @@ LogGP的五个参数: LogGP模型的通信延迟公式为: + $$ T=L+2\times{o}+\frac{n}{G} $$ @@ -60,14 +61,17 @@ nvshmemi_transfer_put_signal AllToAll操作需要每个PE向其他P-1个PE发送消息,每次传输的数据总大小为n。由于CPU代理的串行瓶颈,它必须一个接一个处理P-1个发送请求。 + $$ T_{IBRC} \approx L+2\times o_{IBRC}+\frac{M}{G} $$ + 其中, + $$ M=(P-1) \times n $$ @@ -76,67 +80,71 @@ $$ ## IBRC各步骤耗时 -1. GPU端进行指令的生成与提交(\(T_{GPU}\() +1. GPU端进行指令的生成与提交( $T_{GPU}$ ) - GPU Kernel中transfer_dma所做的工作,包括: - - - 通过atomicAdd在环形队列中预留空间 - - 执行check_channel_availability进行流控,请求过多时可能会导致等待 - - 利用位运算,将PUT操作的详细信息(如远程地址的roffset、操作类型、group_size、标志位flag、laddr、size等),注意构建了4个8字节的指令包 - - 通过volatile 64位内存写入,将指令包传给环形队列 - - 该部分耗时主要在GPU上的原子操作、内存读写以及可能的自旋等待组成,在环形队列未满时,耗时较短且相对固定。 - - - $$ - T_{GPU}=T_{atomicAdd}+T_{flowControl}+T_{buildPackets} - $$ - - -2. GPU与CPU的切换,包括通信延迟与唤醒延迟($T_{syncWakeup}$) +GPU Kernel中transfer_dma所做的工作,包括: - - GPU需要通过__threadfence()确保其写入的指令对CPU可见,且GPU需要通过PCIE向主机内存中写入指令 - - 内核调度器唤醒CPU Proxy,涉及到一次上下文切换 +- 通过atomicAdd在环形队列中预留空间 +- 执行check_channel_availability进行流控,请求过多时可能会导致等待 +- 利用位运算,将PUT操作的详细信息(如远程地址的roffset、操作类型、group_size、标志位flag、laddr、size等),注意构建了4个8字节的指令包 +- 通过volatile 64位内存写入,将指令包传给环形队列 - - $$ - T_{syncWakeup}=T_{GPUFence}+T_{PCIe}+T_{shedule} - $$ - +该部分耗时主要在GPU上的原子操作、内存读写以及可能的自旋等待组成,在环形队列未满时,耗时较短且相对固定。 -3. CPU端指令处理($T_{CPUproxy}$) - CPU Proxy中process_channel_dma函数所做的工作 +$$ +T_{GPU}=T_{atomicAdd}+T_{flowControl}+T_{buildPackets} +$$ + - - 读取并等待上面四个指令,其中会用到__sync_synchronize()这个内存栅栏,有较大的时间开销。在这一阶段能够重组获得laddr、size、pe、op、rptr - - 之后提交传输操作,通过nvshmemi_process_multisend_rma执行具体的网络传输 +2. GPU与CPU的切换,包括通信延迟与唤醒延迟( $T_{syncWakeup}$ ) - 该部分耗时主要是同步开销。 +- GPU需要通过__threadfence()确保其写入的指令对CPU可见,且GPU需要通过PCIE向主机内存中写入指令 +- 内核调度器唤醒CPU Proxy,涉及到一次上下文切换 - - $$ - T_{CPUproxy}=T_{spinWait}+T_{CPUfence} - $$ - -4. 网络传输($T_{Network}$) - 这部分由`nvshmemi_process_multisend_rma` 函数及其调用的底层网络库(如 `libibverbs`)所做的工作。 +$$ +T_{syncWakeup}=T_{GPUFence}+T_{PCIe}+T_{shedule} +$$ - - 进行内存注册,获取内存密钥lkey/rkey - - 根据数据大小决定是否进行数据分块 - - 调用网络库API,由库函数创建WQE - - Ringing the Doorbell,启动DMA传输 - 该部分即LogGP的主体部分 +3. CPU端指令处理( $T_{CPUproxy}$ ) + +CPU Proxy中process_channel_dma函数所做的工作 + +- 读取并等待上面四个指令,其中会用到__sync_synchronize()这个内存栅栏,有较大的时间开销。在这一阶段能够重组获得laddr、size、pe、op、rptr +- 之后提交传输操作,通过nvshmemi_process_multisend_rma执行具体的网络传输 + +该部分耗时主要是同步开销。 + + + +$$ +T_{CPUproxy}=T_{spinWait}+T_{CPUfence} +$$ - - $$ - T_{Network}=T_{lib}+L+\frac{M}{G} - $$ - - 其中$T_{lib}$是调用网络库函数的开销 +4. 网络传输( $T_{Network}$ ) + +这部分由`nvshmemi_process_multisend_rma` 函数及其调用的底层网络库(如 `libibverbs`)所做的工作。 + +- 进行内存注册,获取内存密钥lkey/rkey +- 根据数据大小决定是否进行数据分块 +- 调用网络库API,由库函数创建WQE +- Ringing the Doorbell,启动DMA传输 + +该部分即LogGP的主体部分 + + + +$$ +T_{Network}=T_{lib}+L+\frac{M}{G} +$$ + + + +其中$T_{lib}$是调用网络库函数的开销 因此,对于小消息而言,其总延迟有很大程度上受到前三个阶段的影响,特别是CPU Proxy对于指令的串行执行与上下文切换,导致其瓶颈主要在CPU端,带宽难以充分利用。而大消息因其单次指令传输数据大,主要瓶颈在带宽方面,故其对带宽的利用率较高,与IBGDA类似。 @@ -149,9 +157,12 @@ $$ ## Thread 1. 该线程独自调用ibgda_get_qp()获取与目标PE通信的QP,调用ibgda_get_lkey/ibgda_raddr_rkey获取本地和远程内存的内存密钥,并确定这些密钥能覆盖的最大数据范围 + 2. 根据传输的数据量和密钥的覆盖范围,决定是采取方案1还是方案2。 - - 方案1:当全部数据可以一次性完整传输时,调用ibgda_reserve_wqe_slots在网卡命令队列中预留所需的所有WQE槽位,并依次写入PUT和Signal的WQE,最后调用ibgda_submit_requests通知网卡开始工作。 - - 方案2:当数据总量超过了单次传输上限时,对数据进行分块,通过循环,按照“获取当前块密钥、预留WQE、写入WQE、提交”的顺序执行,直到将所有数据块都传输完毕。 + +- 方案1:当全部数据可以一次性完整传输时,调用ibgda_reserve_wqe_slots在网卡命令队列中预留所需的所有WQE槽位,并依次写入PUT和Signal的WQE,最后调用ibgda_submit_requests通知网卡开始工作。 +- 方案2:当数据总量超过了单次传输上限时,对数据进行分块,通过循环,按照“获取当前块密钥、预留WQE、写入WQE、提交”的顺序执行,直到将所有数据块都传输完毕。 + 3. 如果不是非阻塞式的,则调用ibgda_quiet,等待网卡确认所有任务完成,GPU不断轮询CQ来判断传输是否完成。 在IBGDA中,发起通信的处理器是GPU,由其SM直接向NIC发送指令。 @@ -164,6 +175,7 @@ $$ + $$ T_{IBGDA} \approx L+2\times o_{IBGDA}+\frac{M}{G} $$ @@ -173,6 +185,7 @@ $$ 其中, + $$ M=(P-1) \times n $$ From 039b1e75a9038e3be365e49b71d38d3b207a356f Mon Sep 17 00:00:00 2001 From: zzs Date: Wed, 10 Sep 2025 23:08:32 +0800 Subject: [PATCH 5/5] issue8 --- src/code/issue8/AllToAll.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/code/issue8/AllToAll.md b/src/code/issue8/AllToAll.md index 70f0b5c..c8cf701 100644 --- a/src/code/issue8/AllToAll.md +++ b/src/code/issue8/AllToAll.md @@ -193,3 +193,31 @@ $$ ## IBGDA各步骤耗时 IBRC在执行传输时,GPU需要向CPU Proxy发送特定地指令,让CPU Proxy解析指令获得构造wqe的信息。而IBGDA跳过了这一系列步骤,由GPU直接生成wqe,并将其写入网卡。由于GPU是SIMT的编程模型,单个warp内的多个thread可以同时向网卡写入wqe,因此避免了小消息时,带宽利用不充分的问题。 + +1. 准备阶段( $T_{prep}$ ) + +Kernel会获取QP、DCT、lkey、raddr、rkey等RDMA通信必须的元素,同时判断数据能否一次性传输。 + +该步骤是一个固定的、较小的软件开销。 + +2. 执行阶段( $T_{exec}$ ) + +Kernel调用ibgda_reserve_wqe_slots预留wqe空间,ibgda_write_rdma_write_wqe向网卡的指令队列写入RDMA WRITE指令,最终调用ibgda_submit_requests通知网卡开始执行数据传输。这一步骤是GPU为了发起通信而被占用的时间,耗时主要是多次的MMIO写入,由GPU向网卡直接写wqe。 + +在RDMA WRITE的wqe写入完成后,还会追加一个信令提交,表明传输完成。其与数据传输的提交是串行执行的,总耗时为两者之和。 + +3. 等待阶段( $T_{wait}$ ) + +如果Kernel是阻塞调用,会在最后执行ibgda_quiet,该函数读取最后一个WQE的编号prod_idx,并进入自旋等待,不断轮询完成队列CQ,直到获取目标prod_idx编号的CQE,意味着该任务已经被硬件执行完毕。此时ibgda_quiet等待结束,函数返回。 + +# 小结 + +| | IBRC(CPU Proxy) | IBGDA | +| ---------- | --------------------------------------------------------- | --------------------------------------- | +| 实现 | GPU 写指令,CPU Proxy根据指令发起通信 | GPU直接编程,与网卡直接通信 | +| 通信路径 | GPU → 指令队列(CPU内存) → CPU代理 → 网络库 → 网卡 | GPU → WQE队列(网卡内存) → 网卡 | +| 小消息延迟 | 高。软件栈长,且受限于CPU串行处理能力和GPU与CPU通信的开销 | 低。软件开销很小,直接控制网卡 | +| 大消息延迟 | 低。由于数据的增大,瓶颈主要在网络带宽,两者相差不大 | 低。但由于GPU的并行能力,更容易打满带宽 | + + +