在 MPI 进程之间交换数据(晕)
Posted
技术标签:
【中文标题】在 MPI 进程之间交换数据(晕)【英文标题】:Exchange Data Between MPI processes (halo) 【发布时间】:2013-07-08 22:50:46 【问题描述】:鉴于以下情况,我有 N 个 MPI 进程,每个进程都有一个对象。当通信阶段到来时,来自这些对象的“通常很小”的数据将被交换。 一般来说,任意两个节点之间都有数据交换。
什么是最好的策略?:
在任何节点 X 中,为与该节点 X 建立连接的每个其他节点创建两个缓冲区。然后在对等基础上进行发送/接收。在每个节点X中,创建一个缓冲区来收集所有要通信的光环数据。然后“bcast”那个缓冲区。
还有其他我不知道的策略吗?
【问题讨论】:
【参考方案1】:对于最近邻样式的光环交换,通常最有效的实现之一是使用一组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
,即可执行整个多维光环交换。
【讨论】:
【参考方案2】:您在问题中使用的词 halo 表明您可能正在设置一个跨进程拆分的计算域。这是 MPI 程序中广泛应用的一种非常常见的方法。通常每个进程在其本地域上进行计算,然后所有进程与其邻居交换光环元素,然后重复直到满意。
虽然您可以创建专用缓冲区来交换光环元素,但我认为更常用的方法,当然也是明智的第一种方法,是将光环元素本身视为您正在寻找的缓冲区。例如,如果你有一个 100x100 的计算域,分布在 100 个进程中,每个进程都会得到一个 12x12 的本地域——这里我假设与 4 个正交邻居中的每一个有 1 个单元重叠,并注意全局域的边缘.晕细胞是每个局部域边界中的那些细胞,在通信之前无需将元素编组到另一个缓冲区中。
如果我猜对了您尝试实现的计算类型,您应该查看mpi_cart_create
及其相关函数;这些旨在使设置和实施程序变得容易,其中计算步骤与相邻进程之间的通信步骤交错。网络上充斥着创建和使用此类笛卡尔拓扑的示例。
如果这是您计划的计算方式,那么mpi_bcast
绝对是错误的使用方式。 MPI 广播(和类似功能)是所有进程(在给定通信器中)参与的集体操作。广播对于全球通信很有用,但光环交换是本地通信。
【讨论】:
以上是关于在 MPI 进程之间交换数据(晕)的主要内容,如果未能解决你的问题,请参考以下文章