2013-03-05 83 views
1

对不起,如果这个问题是常见或微不足道的,我对MPI不是很熟悉,所以请耐心等待。MPI同步矩阵的向量

我有一个向量矩阵。每个矢量都是空的或者有几个项目。

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

当我启动程序的每个进程将在这个矩阵相同的数据,但随着代码的进展每个进程可能会从一些载体删除多个项目,并把他们在其他载体。

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

我该如何去确保每个进程在屏障后都有正确的更新矩阵?编辑: 对不起,我不清楚。每个进程可以将一个或多个对象移动到另一个向量,但只有一个进程可以移动每个对象。换句话说,每个进程都有一个可能移动的对象列表,但矩阵可能会被所有人改变。而且两个进程无法移动同一个对象。

+0

如果每个处理器都操纵任何可能的元素,那么你会怎样决定“正确更新的矩阵”是什么? – 2013-03-05 13:11:19

+0

对不起,我不清楚。每个进程可以将一个或多个对象移动到另一个向量,但只有一个进程可以移动每个对象。 – Chippen 2013-03-05 13:25:09

回答

1

在这种情况下,您需要使用MPI_Bcast发送消息,通知其他处理器这一点,并指示他们也这样做。或者,如果排序并不重要,直到您触及屏障,则您只能将消息发送到执行排列的根进程,然后在屏障将其发送给所有其他人后使用MPI_Bcast

还有一件事:指针向量通常是一个坏主意,因为您需要在那里手动管理内存。如果您可以使用C++ 11,则可以使用std::unique_ptrstd::shared_ptr(取决于您的语义),也可以使用提供非常类似功能的Boost。

最后,将一个矩阵表示为一个固定大小的数组的固定大小数组是非常糟糕的。首先:矩阵大小是固定的。第二:相邻的行不一定存储在连续的内存中,像疯了一样放慢你的程序(它实际上可以是数量级)。而是将矩阵表示为大小为Nrows*Ncols的线性阵列,然后将元素索引为Nrows*i + j,其中Nrows是行数,ij分别是行和列索引。如果您不想要列专业存储,请按i + Ncols*j处理元素。你可以把这个索引转换成几乎没有开销的内联函数。

+0

谢谢,我不确定如何将这些说明只发送给根,但我可以弄清楚。至于矩阵部分,我目前并不需要速度,但我同意这将是一个更好的解决方案。我会试试这个! – Chippen 2013-03-05 13:48:36

+0

然后你应该看看[MPI文档](http://www.mpi-forum.org/docs/docs.html)。它非常易读,并包含大量示例。 – 2013-03-05 13:53:01

+0

在C中,静态二维数组中的元素被连续存储(逐行,在8.3.4中定义)。所以如果你适当地访问它们,它们不是性能问题。 (但还有其他问题。) – Zulan 2013-03-05 13:54:24

1

我会建议以不同的铺陈数据:

每个进程都有地图了对象及其在矩阵位置。这是如何实现取决于你如何识别对象。如果所有本地对象都被编号,则可以使用vector<pair<int,int>>

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

这可能会或可能不会表现良好。其他优化(如共享“交易”)完全取决于您的对象以及您对它们执行的操作。