使用小数据集和大数据集时,MPI_Barrier与MPI_Gather有什么区别?

5
我一直在使用MPI_Scatter / MPI_Gather进行各种并行计算。我注意到MPI_Barrier()通常被调用以同步处理器,类似于OpenMP barrier指令。我正在为一个项目调整我的代码,并注释掉了下面的MPI_Barrier()行,发现计算仍然是正确的。为什么会这样?我可以理解为什么需要第一个MPI_Barrier(),其他处理器不需要等待;一旦它们从主处理器获得数据,它们就可以开始计算。但是,在MPI_Gather之后是否需要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?

1
此外,MPI 的缓冲功能会为您执行一些默认的安全工作。您的“发送方”将把数据发送到“接收方”系统缓冲区。然后在“接收方”内部,它将从系统缓冲区转移您的数据到应用程序缓冲区。因此,对于少量数据,您可以认为您的程序是安全的。 - RandomEli
1
关于您的编辑:不,数据大小在这种情况下没有影响正确性。 - Zulan
2个回答

6

没有必要使用屏障!

MPI_Gather是一个阻塞操作,也就是说,在调用完成后输出结果才可用。这并不意味着需要屏障,因为非根进程可以但不保证在根/其他进程开始操作之前完成。然而,在MASTER_ID进程上访问global,并在本地调用完成后在任何进程上重用localdata是完全安全的。

与基于消息的MPI相比,共享内存OpenMP的同步方式不同。对于阻塞通信,通常不需要显式同步-结果保证在调用完成后可用。

对于非阻塞通信,需要某种形式的同步,但是可以通过特定消息上的MPI_Test/MPI_Wait来完成-如果您尝试使用MPI_Barrier替换MPI_Wait,则屏障甚至可能提供错误的正确性感觉。对于单边通信,情况会变得更加复杂,屏障可以发挥作用。

实际上,您很少需要屏障,相反,请避免使用它们以避免引入任何不必要的同步。

编辑:鉴于其他答案的矛盾,这里是标准(MPI 3.1,第5.1节)引用(重点在我身上)。

集体操作可以(但不一定)在调用者参与集体通信完成后立即完成。 阻塞操作在调用返回时立即完成。非阻塞(即时)调用需要单独的完成调用(参见第3.7节)。 集体操作的完成表明调用者可以自由修改通信缓冲区中的位置。它并不表示组中的其他进程已经完成或甚至开始操作(除非操作的描述另有说明)。因此,集体通信操作可能具有同步所有调用进程的效果,也可能没有。当然,这个声明不包括屏障操作。

针对最近的编辑:不,数据大小在这种情况下不会影响正确性。 MPI中的数据大小有时会影响不正确的MPI程序是否会死锁。


2

MPI_Gather()没有内部隐式屏障。

问题:在收集后是否需要屏障?

不需要。

正如您可以在何时需要使用MPI_Barrier()?中阅读到的:

MPI-3.0之前的所有集体操作都是阻塞的,这意味着在它们返回后使用传递给它们的所有缓冲区是安全的。特别是,这意味着当其中一个函数返回时,所有数据都已接收。(但这并不意味着所有数据都已发送!)因此,在集体操作之前/之后,如果所有缓冲区已经有效,则MPI_Barrier不是必需的(或非常有帮助)。


1
除了MPI_Gather不意味着屏障之外,这是绝对错误的。 MPI_Gather是阻塞的。你在这里不使用共享内存模型。 - Zulan
@Zulan 谢谢,回答已更新。不过,我让我们的答案仍然是独特的。顺便说一句,你的回答很好! - gsamaras

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接