我想提高代码的效率,其中包括更新数组的每个值,这些值在使用 MPI 运行的所有处理器上都是相同的。我现在拥有的基本结构是将数据 block memcpy 到每个处理器上的本地数组中,对它们进行操作,然后使用 Allgatherv(必须使用“v”,因为本地 block 的大小并不严格相同)。
在 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);
事实证明,这不是很有效。事实上,它真的非常慢,非常糟糕,对于我感兴趣的大多数系统规模,并行化不会导致速度的任何提高。
我想另一种方法是只更新每个处理器上全局 vector 的本地 block ,然后将正确的内存块从正确的任务广播到所有其他任务。虽然这避免了显式内存处理,但广播的通信成本必须相当高。它实际上是万能的。
编辑:我刚刚去尝试了这个解决方案,您必须在其中循环处理多个任务并执行该数量的广播语句。这种方法更糟糕。
谁有更好的解决方案?
最佳答案
您描述的算法是“all to all”。每个等级更新更大数组的一部分,并且所有等级必须不时同步该数组。
如果更新发生在程序流中的受控点,则收集/分散模式可能会有所帮助。所有等级将他们的更新发送给“等级 0”,等级 0 将更新后的数组发送给其他所有人。根据阵列大小、列数、每个列之间的互连等......此模式可能提供比 Allgatherv 更少的开销。
关于c - 使用 MPI 在所有任务上有效地更新相同的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7437418/