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++的主要内容,如果未能解决你的问题,请参考以下文章