对不起,如果这个问题很常见或者是微不足道的话,我对MPI不是很熟悉,所以请耐心等待。
我有一个向量矩阵。每个向量都是空的或其中有几个项目。
std::vector<someStruct*> partitions[matrix_size][matrix_size];
当我启动程序时,每个进程在此矩阵中将具有相同的数据,但随着代码的进展,每个进程可能会从某些向量中删除多个项目并将它们放在其他向量中。
因此,当我到达障碍时,我不得不确保每个进程都具有此矩阵的最新版本。最大的问题是每个过程都可能操纵任何或所有向量。
我如何确保每个进程在屏障后都有正确的更新矩阵?
编辑: 对不起,我不清楚。每个进程可以将一个或多个对象移动到另一个向量,但是只有一个进程可以移动每个对象。换句话说,每个进程都有一个可以移动的对象列表,但是每个人都可以更改矩阵。并且两个进程无法移动同一个对象。
答案 0 :(得分:1)
在这种情况下,您需要使用MPI_Bcast
发送消息,通知其他处理器,并指示他们这样做。或者,如果在您触及屏障之前排序无关紧要,则只能将消息发送到执行排列的根进程,然后在屏障使用MPI_Bcast
将其发送给所有其他人之后。
还有一件事:指针向量通常是个坏主意,因为你需要在那里手动管理内存。如果您可以使用C ++ 11,请使用std::unique_ptr
或std::shared_ptr
(取决于您的语义),或使用提供非常类似功能的Boost。
最后,将矩阵表示为固定大小数组的固定大小数组是非常糟糕的。首先:矩阵大小是固定的。第二:相邻的行不一定存储在连续的内存中,像疯了一样减慢你的程序速度(字面上可以是数量级)。而是将矩阵表示为大小为Nrows*Ncols
的线性数组,然后将元素索引为Nrows*i + j
,其中Nrows
是行数,i
和j
分别是行索引和列索引。如果您不想要列主要存储,请按i + Ncols*j
来处理元素。您可以将这个索引包装在几乎没有开销的内联函数中。
答案 1 :(得分:1)
我建议以不同方式布置数据:
每个过程都有一个他的对象的图和它们在矩阵中的位置。如何实现取决于您如何识别对象。如果所有本地对象都已编号,则可以使用vector<pair<int,int>>
。
将其视为您操纵的主要结构,并将该结构与MPI_Allgather
进行通信(每个进程将数据发送到所有其他进程,最后每个人都拥有所有数据)。如果您需要通过坐标快速查找,那么您可以构建缓存。
这可能会也可能不会表现良好。其他优化(如共享'事务')完全取决于您的对象以及您对它们执行的操作。