MPI同步矩阵的向量

MPI synchronize matrix of vectors

本文关键字:向量 同步 MPI      更新时间:2023-10-16

如果这个问题很常见或微不足道,请原谅,我不是很熟悉MPI,所以请原谅我。

我有一个向量矩阵。每个vector都是空的,或者只有几个元素。

std::vector<someStruct*>  partitions[matrix_size][matrix_size];

当我启动程序时,每个进程在这个矩阵中都有相同的数据,但是随着代码的进展,每个进程可能会从一些向量中删除一些项,并将它们放入其他向量中。

所以当我到达一个障碍时,我必须以某种方式确保每个进程都有这个矩阵的最新版本。最大的问题是每个进程可能操作任何或所有向量。

我如何确保每个进程在屏障之后都有正确的更新矩阵?

编辑:对不起,我没有说清楚。每个进程可以将一个或多个对象移动到另一个向量上,但只有一个进程可以移动每个对象。换句话说,每个进程都有一个可以移动的对象列表,但是每个进程都可以改变矩阵。两个进程永远不能移动同一个对象

在这种情况下,您需要使用MPI_Bcast发送消息,通知其他处理器此消息,并指示它们也这样做。或者,如果在遇到屏障之前顺序无关紧要,则只能将消息发送给执行排列的根进程,然后在屏障将其发送给使用MPI_Bcast的所有其他进程。

还有一件事:指针向量通常是一个非常糟糕的主意,因为你需要手动管理那里的内存。如果您可以使用c++ 11,请使用std::unique_ptrstd::shared_ptr代替(取决于您的语义是什么),或者使用提供非常类似功能的Boost。

最后,将矩阵表示为固定大小数组的固定大小数组是非常糟糕的。第一:矩阵大小是固定的。第二:相邻的行不一定存储在连续的内存中,这会使您的程序疯狂地变慢(实际上可能是数量级)。相反,将矩阵表示为大小为Nrows*Ncols的线性数组,然后将元素索引为Nrows*i + j,其中Nrows为行数,ij分别为行和列索引。如果您不希望使用列为主存储,则通过i + Ncols*j对元素进行寻址。您可以将这种索引杂活包装在几乎没有开销的内联函数中。

我建议以不同的方式布局数据:

每个进程都有其对象及其在矩阵中的位置的映射。如何实现取决于您如何识别对象。如果所有的局部对象都有编号,则可以使用vector<pair<int,int>>

将其视为您操作的主要结构并与MPI_Allgather进行通信(每个进程将其数据发送给所有其他进程,最后每个进程都拥有所有数据)。如果你需要通过坐标快速查找,那么你可以建立一个缓存。

可能表现良好,也可能表现不佳。其他优化(如共享"事务")完全取决于你的对象和你对它们执行的操作。