繁体   English   中英

在MPI进程之间交换数据(光晕)

[英]Exchange Data Between MPI processes (halo)

给定以下情况,我有N个MPI进程,每个进程都有一个对象。 在通信阶段到来时,将交换来自这些对象的“通常很小”的数据。 通常,任何两个节点之间都有数据交换。

最佳策略是什么?

  • 在任何节点X中,为与此节点X连接的每个其他节点创建拖缓冲区,然后在对等基础上进行发送/接收。
  • 在每个节点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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM