MPI屏障C++;
我想在windows上使用MPI(MPICH2)。我写这个命令:MPI屏障C++;,mpi,barrier,Mpi,Barrier,我想在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 = " <
MPI_Barrier(MPI_COMM_WORLD);
我希望它会阻塞所有处理器,直到所有组成员都调用它。但事实并非如此。我添加代码的示意图:
int a;
if(myrank == RootProc)
a = 4;
MPI_Barrier(MPI_COMM_WORLD);
cout << "My Rank = " << myrank << "\ta = " << a << endl;
inta;
if(myrank==RootProc)
a=4;
MPI_屏障(MPI_通信世界);
cout变量a
未初始化-这可能就是它显示该数字的原因。在MPI中,变量a
在进程之间重复-因此a
有两个值,其中一个未初始化。你想写:
int a = 4;
if (myrank == RootProc)
...
或者,在根目录(id 0)中执行MPI_send
,在从目录(id 1)中执行MPI_recv
,以便在从目录中也设置根目录中的值
注意:这段代码会在我的脑海中触发一个小警报,所以我需要检查一些东西,我会用更多信息编辑它。但在此之前,未初始化的值肯定是您的问题。
好的,我已经检查了事实-您的代码没有正确缩进,我错过了丢失的{}
。屏障现在看起来很好,尽管您发布的代码片段没有做太多的工作,并且不是屏障的一个很好的示例,因为从机直接输入它,而root将变量的值设置为4
,然后输入它。要测试它是否真的有效,您可能需要在其中一个进程中使用某种睡眠机制—这将同时产生(希望这是正确的术语)另一个进程,防止它在睡眠结束之前打印cout
。您只在进程0中分配a
。MPI不共享内存,因此如果希望进程1中的a
获得4的值,则需要从进程0调用MPI\u Send
,从进程1调用MPI\u Recv
。阻塞是不够的,必须将数据发送到其他进程(进程之间未共享的内存)
要跨所有流程共享数据,请使用:
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);
在这里,您将一个由&a表单进程0指向的整数发送给所有其他整数。
//MPI\u Bcast对于根进程是发送方,对于非根进程是接收方
您还可以通过以下方式向specyfic流程发送一些数据:
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)
谢谢这是真的,但我还有一个问题。据我所知,barrier会阻止调用者,直到所有组成员都调用了它,但我测试并看到进程1通过了这个函数(通过编写一个句子cout),根进程(0)在barrier之前。有什么问题吗?感谢您不能信任来自不同进程的输出语句的顺序。如果您不确定,请确保您的时钟在屏障前后同步并输出time()
。不要期望不同处理器上的时钟处于如此紧密的同步状态,以至于它们报告的时间允许您对输出语句进行正确排序。MPI_屏障同步进程,而不是时钟。在您完成了大量MPI编程(如几年的实际实践)之前,我认为您甚至不应该忘记MPI_屏障工作不正常。我使用过的所有MPI库都是在产品质量方面享有盛誉的组织中编写的。如果您认为某个屏障有问题,那么您犯错误(在思考或编码方面)的可能性比屏障本身有问题的可能性要大得多。