【问题标题】:Efficiently update an identical array on all tasks with MPI使用 MPI 有效地更新所有任务上的相同数组
【发布时间】:2011-09-19 23:50:31
【问题描述】:

我想提高代码的效率,其中包括对数组的每个值的更新,这在所有使用 MPI 运行的处理器上都是相同的。我现在拥有的基本结构是将数据块 memcpy 到每个处理器上的本地数组中,对它们进行操作,然后 Allgatherv(必须使用“v”,因为本地块的大小并不完全相同)。

在 C 中,这看起来像:

/* counts gives the parallelization, counts[RANK] is the local memory size */
/* offsets gives the index in the global array to the local processors */

memcpy (&local_memory[0], &total_vector[0], counts[RANK] * sizeof (double));
for (i = 0; i < counts[RANK]; i++)
  local_memory[i] = new_value;

MPI_Allgatherv (&local_memory[0], counts[RANK], MPI_DOUBLE, &total_vector[0], counts, offsets, MPI_DOUBLE, MPI_COMM_WORLD);

事实证明,这不是很有效。事实上,它真的非常慢,非常糟糕,以至于对于我感兴趣的大多数系统规模,并行化并没有带来任何速度的提升。

我想另一种方法是只更新每个处理器上全局向量的本地块,然后将正确的内存块从正确的任务广播到所有其他任务。虽然这避免了显式内存处理,但广播的通信成本必须相当高。它实际上是全方位的。

编辑:我刚刚尝试了这个解决方案,你必须循环任务数量并执行该数量的广播语句。这种方法更糟糕。

谁有更好的解决方案?

【问题讨论】:

  • 为了确保我理解正确:每个处理器都需要对向量的特定部分进行更新。所有处理器最终都需要从所有其他处理器获得更新吗? (因为它们应该是相同的)
  • 我正要发布一个关于它如何变得更好或更糟的答案,而你自己回答了。我没主意了。使用自定义 MPI 数据类型可能是可行的,但我对这些不太熟悉。
  • 是的,我确实在我的 MPI 语句中使用了自定义数据类型,我只是发布了上述想法的一个简单版本。使用更大的块可以使聚集更快,但我认为主要问题是不断需要将全局向量复制到每个处理器上的本地内存。这是很多工作。从根本上说,最好的选择是只分发数组,但不幸的是我的其余代码还不能支持它,所以我正在寻找魔法。哈哈。

标签: c mpi


【解决方案1】:

你描述的算法是“all to all”。每个等级更新较大数组的一部分,并且所有等级必须不时同步该数组。

如果更新发生在程序流程中的受控点,则聚集/分散模式可能是有益的。所有等级都将其更新发送到“等级 0”,等级 0 将更新后的数组发送给其他所有人。根据阵列大小、列数、每个列之间的互连等......这种模式可能比 Allgatherv 提供更少的开销。

【讨论】:

    猜你喜欢
    • 2015-08-07
    • 1970-01-01
    • 1970-01-01
    • 2016-01-25
    • 2017-12-12
    • 2017-07-13
    • 2021-07-03
    • 1970-01-01
    • 2022-08-14
    相关资源
    最近更新 更多