使用MPI有效地更新所有任务上的相同阵列

时间:2011-09-15 21:02:33

标签: c mpi

我想提高代码的效率,其中包括对所有使用MPI运行的处理器上相同的数组值的更新。我现在的基本结构是将数据块存储到每个处理器上的本地数组中,对它们进行操作,以及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);

事实证明,这不是很有效。事实上,它真的很慢,非常糟糕,对于大多数系统尺寸,我对并行化感兴趣并不会导致速度增加。

我认为替代方法是在每个处理器上仅更新全局向量的本地块,然后将正确的内存块从正确的任务广播到所有其他任务。虽然这避免了显式的存储器处理,但广播的通信成本必须非常高。它实际上是全部的。

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

任何人都有更好的解决方案吗?

1 个答案:

答案 0 :(得分:0)

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

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