【发布时间】: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 语句中使用了自定义数据类型,我只是发布了上述想法的一个简单版本。使用更大的块可以使聚集更快,但我认为主要问题是不断需要将全局向量复制到每个处理器上的本地内存。这是很多工作。从根本上说,最好的选择是只分发数组,但不幸的是我的其余代码还不能支持它,所以我正在寻找魔法。哈哈。