对于最近邻样式的光环交换,通常最有效的实现之一是使用一组MPI_Sendrecv 调用,通常每个维度两个:
半步一 - 正向传输数据:每个等级从其左侧接收并进入其左侧光环,并将数据发送到其右侧的等级
+-+-+---------+-+-+ +-+-+---------+-+-+ +-+-+---------+-+-+
--> |R| | (i,j-1) |S| | --> |R| | (i,j) |S| | --> |R| | (i,j+1) |S| | -->
+-+-+---------+-+-+ +-+-+---------+-+-+ +-+-+---------+-+-+
(S 指定正在传递的本地数据部分,而R 指定接收数据的光环,(i,j) 是进程网格中排名的坐标)
半步二 - 向负方向传输数据:每个等级从其右侧接收并进入其右侧光环,并将数据发送到其左侧的等级
+-+-+---------+-+-+ +-+-+---------+-+-+ +-+-+---------+-+-+
<-- |X|S| (i,j-1) | |R| <-- |X|S| (i,j) | |R| <-- |X|S| (i,j+1) | |R| <--
+-+-+---------+-+-+ +-+-+---------+-+-+ +-+-+---------+-+-+
(X是上半步已经填充的晕区部分)
大多数交换网络支持多个同时双向(全双工)通信,整个交换的延迟为
上述两个半步的重复次数与域分解的维数一样多。
该过程在标准的 3.0 版中更加简化,引入了所谓的邻里集体通信。只需一次调用MPI_Neighbor_alltoallw,即可执行整个多维光环交换。