Yu *_*hen 4 c synchronization distributed-computing mpi
我一直在使用MPI_Scatter/MPI_Gather进行各种并行计算.我注意到的一件事是MPI_Barrier()通常被称为同步处理器,类似于OpenMP屏障指令.我正在为一个项目调整我的代码并在下面注释掉我的MPI_Barrier()行,并发现计算仍然是正确的.为什么会这样?我可以理解为什么需要第一个MPI_Barrier() - 其他处理器不需要等待; 一旦他们从处理器MASTER获取数据,他们就可以开始计算.但MPI_arather之后是否需要MPI_Barrier,或者MPI_Gather内部是否已经存在隐含障碍?
编辑:在这种情况下,正在处理的数据的大小是否重要?
MPI_Scatter(&sendingbuffer,sendingcount,MPI_FLOAT,receivingbuffer,sendcount,
MPI_INT,MASTER_ID,MPI_COMM_WORLD);
// PERFORM SOME COMPUTATIONS
MPI_Barrier(); //<--- I understand why this is needed
MPI_Gather(localdata,sendcount, MPI_INT, global,sendcount, MPI_INT, MASTER_ID, MPI_COMM_WORLD);
//MPI_Barrier(); <------ is this ever needed?
Run Code Online (Sandbox Code Playgroud)
不需要任何障碍!
MPI_Gather是阻塞操作,即调用完成后输出可用.这并不意味着障碍,因为在根/其他等级开始操作之前,允许非根等级,但不能保证完成.然而,这是完全安全访问global的MASTER_ID等级和重用localdata本地调用完成后的任何排名.
与基于消息的MPI同步与共享内存OpenMP不同.对于阻止通信,通常不需要显式同步 - 保证在调用完成后可以获得结果.
对于非阻塞通信来说,同类排序是必要的,但这是通过MPI_Test/ MPI_Wait在特定消息上完成的- 如果你试图用a替换MPI_Wait,障碍甚至可能提供错误的正确感MPI_Barrier.通过片面沟通,它变得更加复杂,障碍可以发挥作用.
实际上,您很少需要屏障,而是避免它们不引入任何不必要的同步.
编辑:鉴于其他答案的矛盾,这里是标准(MPI 3.1,第5.1节)引用(强调我的).
一旦呼叫者参与集体通信完成,集体操作就可以(但不是必须)完成.一旦调用返回,阻塞操作就完成了.非阻塞(立即)呼叫需要单独的完成呼叫(参见第3.7节).集合操作的完成表明调用者可以自由地修改通信缓冲区中的位置.它并不表示组中的其他进程已完成或甚至已开始操作(除非操作说明另有暗示).因此,集体通信操作可以或可以不具有同步所有调用进程的效果.当然,这一陈述不包括屏障操作.
要解决最近的编辑问题:不,在这种情况下,数据大小对正确性没有影响.MPI中的数据大小有时会影响不正确的MPI程序是否会死锁.