我一直在使用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?
答案 0 :(得分:5)
不需要任何障碍!
MPI_Gather
是阻塞操作,即调用完成后输出可用。这并不意味着障碍,因为在根/其他等级开始操作之前,允许非根等级,但不能保证完成。但是,在global
排名上访问MASTER_ID
并在本地通话完成后在任何排名上重复使用localdata
都非常安全。
与基于消息的MPI同步与共享内存OpenMP不同。对于阻止通信,通常不需要显式同步 - 保证在调用完成后可以获得结果。
非阻塞通信需要同步排序,但这是通过MPI_Test
/ MPI_Wait
对特定消息进行的 - 如果您尝试替换{{},障碍甚至可能会提供错误的正确感。 {1}} MPI_Wait
。通过片面沟通,它变得更加复杂,障碍可以发挥作用。
实际上,您很少需要障碍,而是避免它们不引入任何不必要的同步。
编辑:鉴于其他答案相互矛盾,这里是标准(MPI 3.1,第5.1节)引用(强调我的)。
集体行动可以(但不是必须)尽快完成 因为来电者参与集体沟通是 完了。 一旦通话,阻止操作即告完成 返回。非阻塞(立即)呼叫需要单独完成 致电(参见第3.7节)。 完成集体行动 表示调用者可以自由修改。中的位置 通信缓冲区。它不表示其他进程 小组已完成或甚至开始行动(除非另有说明 由操作说明暗示)。因此,集体 通信操作可能会或可能不会产生影响 同步所有调用进程。本声明不包括 当然,屏障操作。
解决最近的编辑问题:不,在这种情况下,数据大小对正确性没有影响。 MPI中的数据大小有时会影响不正确的MPI程序是否会死锁。
答案 1 :(得分:2)
MPI_Gather()
内部没有隐含障碍。
问题:聚会后屏障是否需要?
没有
您可以阅读When do I need to use MPI_Barrier()?:
MPI-3.0之前MPI中的所有集体操作都是阻塞的 意味着在它们之后使用传递给它们的所有缓冲区是安全的 返回。特别是,这意味着所有数据都是在收到时收到的 这些函数返回。 (但是,它并不意味着所有数据 被发送!)所以MPI_Barrier不是必需的(或非常有用) 集体操作之前/之后,如果所有缓冲区都已有效。