[英]Exchange Data Between MPI processes (halo)
给定以下情况,我有N个MPI进程,每个进程都有一个对象。 在通信阶段到来时,将交换来自这些对象的“通常很小”的数据。 通常,任何两个节点之间都有数据交换。
最佳策略是什么?
在每个节点X中,创建一个缓冲区以收集所有要通信的光环数据。 然后“ bcast”该缓冲区。
还有其他我不知道的策略吗?
对于最近的邻居样式光环交换,最有效的实现之一通常是使用一组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
的单个调用来MPI_Neighbor_alltoallw
。
您在问题中使用“ 光晕 ”一词表示您可能正在建立一个跨过程的计算域。 在广泛的应用程序中,这是MPI程序中非常普遍的方法。 通常,每个进程都在其本地域上进行计算,然后所有进程都与其邻居交换光晕元素,然后重复进行直到满意为止。
虽然您可以创建用于交换光晕元素的专用缓冲区,但我认为更常见的方法(当然是明智的第一种方法)是将光晕元素本身视为您要查找的缓冲区。 例如,如果您将100x100的计算域划分为100个进程,则每个进程将获得12x12的本地域-在这里,我假设与4个正交邻居中的每一个都有一个单元重叠,并注意全局域的边缘。 晕圈单元是每个局部域边界中的那些单元,无需在通信之前将元素编组到另一个缓冲区中。
如果我正确地猜测了您要实现的计算类型,则应查看mpi_cart_create
及其关联的函数; 这些设计旨在使设置和实施程序变得容易,在这些程序中,计算步骤与相邻进程之间进行通讯的步骤相互交错。 网上充斥着创建和使用这种笛卡尔拓扑的例子。
如果这是您计划的计算方式,那么mpi_bcast
绝对是错误的选择。 MPI广播(和类似功能)是所有操作(在给定的通信器中)参与的集体操作。 广播对于全球通信很有用,但光环交换是本地通信。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.