MPI 屏障 C++

Posted

技术标签:

【中文标题】MPI 屏障 C++【英文标题】:MPI Barrier C++ 【发布时间】:2011-01-04 19:02:00 【问题描述】:

我想在 Windows 上使用 MPI (MPICH2)。我写了这个命令:

MPI_Barrier(MPI_COMM_WORLD);  

我希望它会阻止所有处理器,直到所有组成员都调用它。但它不会发生。我添加了我的代码示意图:

int a;  
if(myrank == RootProc)  
   a = 4;  
MPI_Barrier(MPI_COMM_WORLD);  
cout << "My Rank = " << myrank << "\ta = " << a << endl;  

(使用 2 个处理器:)根处理器 (0) 运行正常,但排名为 1 的处理器不知道 a 变量,因此它显示 -858993460 而不是 4

谁能帮帮我? 问候

【问题讨论】:

【参考方案1】:

变量a 未初始化 - 这可能是它显示该数字的原因。在 MPI 中,变量a 在进程之间重复 - 因此a 有两个值,其中一个未初始化。你想写:

int a = 4;
if (myrank == RootProc)
...

或者,或者,在根 (id 0) 中执行 MPI_send,在从属 (id 1) 中执行 MPI_recv,这样根中的值也会在从属中设置。

注意:该代码在我的脑海中触发了一个小警报,因此我需要检查一些内容,然后使用更多信息对其进行编辑。不过在那之前,未初始化的值肯定是你的问题。 好的,我已经检查了事实 - 您的代码没有正确缩进,我错过了丢失的 。屏障现在看起来很好,虽然您发布的 sn-p 并没有做太多,并且不是一个很好的屏障示例,因为从站直接进入它,而根将变量的值设置为4然后输入它。为了测试它是否真的有效,您可能需要在其中一个进程中使用某种睡眠机制——这也会产生(希望它是正确的术语)另一个进程,防止它打印cout,直到睡眠结束结束了。

【讨论】:

【参考方案2】:

您只是在进程 0 中分配 a。MPI 不共享内存,因此如果您希望进程 1 中的 a 获得值 4,则需要从进程 0 调用 MPI_Send和来自进程 1 的 MPI_Recv

【讨论】:

谢谢。这是真的,但我还有一个问题。据我所知,barrier 会阻止调用者,直到所有组成员都调用它,但是我测试并看到进程 1 通过了这个函数(通过写一个句子,cout)并且根进程(0)在屏障之前。有什么问题?谢谢 你不能相信来自不同进程的输出语句的顺序。如果您不确定,请确保您的时钟同步并在屏障前后输出time() 不要期望不同处理器上的时钟如此紧密地同步,以至于它们报告的时间允许您正确排序输出语句。 MPI_Barrier 同步进程,而不是时钟。 在您完成大量 MPI 编程之前,比如几年的扎实实践,我认为您甚至不应该忘记 MPI_Barrier 无法正常工作。我曾经使用过的所有 MPI 库都是在产品质量享有盛誉的组织中编写的。如果您认为障碍有问题,那么您犯了错误(在思考或编码中)的可能性远远大于障碍本身有问题。【参考方案3】:

阻塞是不够的,你必须将数据发送到其他进程(内存在不共享进程之间)。

要在所有进程之间共享数据使用

int MPI_Bcast(void* buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm )

所以在你的情况下:

MPI_Bcast(&a, 1, MPI_INT, 0, MPI_COMM_WORLD);

在这里,您将一个由 & 一个表单进程 0 指向的整数发送给所有其他整数。 //MPI_Bcast 是根进程的发送者和非根进程的接收者

您还可以通过以下方式将一些数据发送到特定进程:

int MPI_Send( void *buf, int count, MPI_Datatype datatype, int dest, 
              int tag, MPI_Comm comm )

然后通过以下方式接收:

int MPI_Recv(void* buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status)

【讨论】:

以上是关于MPI 屏障 C++的主要内容,如果未能解决你的问题,请参考以下文章

为啥我会收到使用 MPI 屏障 [c++] 的致命错误

MPI 屏障 C++

MPI 中的屏障:如何实现屏障以使进程相互等待

MPI_Barrier - 只有一些进程通过屏障

MPI_Type_commit 是不是隐式调用 MPI_COMM_WORLD 中所有进程的屏障?

MPI 屏障不阻塞文件写入、刷新和 os.fsync