Parallel processing MPI_Bcast()之前的屏障?

Parallel processing MPI_Bcast()之前的屏障?,parallel-processing,mpi,synchronized,Parallel Processing,Mpi,Synchronized,我看到一些开源代码在广播根值之前使用MPI_屏障: MPI_Barrier(MPI_COMM_WORLD); MPI_Bcast(buffer, N, MPI_FLOAT, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); 我不确定MPI\u Bcast()是否已经具有自然阻塞功能。如果这是真的,我可能不需要MPI\u Barrier()来同步所有核心的进度。那么我只能使用: MPI_Bcast(buffer, N, MPI_FLOAT, 0,

我看到一些开源代码在广播根值之前使用MPI_屏障:

MPI_Barrier(MPI_COMM_WORLD);
MPI_Bcast(buffer, N, MPI_FLOAT, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
我不确定
MPI\u Bcast()
是否已经具有自然阻塞功能。如果这是真的,我可能不需要
MPI\u Barrier()
来同步所有核心的进度。那么我只能使用:

MPI_Bcast(buffer, N, MPI_FLOAT, 0, MPI_COMM_WORLD);

那么,哪一个是正确的呢?

很少需要在MPI中执行显式同步,这样的代码通常没有什么意义。MPI中的列组主要在本地处理数据,不共享对全局对象的访问,并且隐式地按照发送和接收操作的语义进行同步。当
i
在本地处理接收到的数据时,为什么秩
i
应该关心其他秩
j
是否接收到广播

在以下情况下,通常需要明确的障碍:

  • 基准测试-在代码的某个定时区域之前设置一个障碍,以消除由于一个或多个列组迟到而导致的任何额外等待时间
  • 并行I/O—在这种情况下,存在一个全局对象(共享文件),其内容的一致性可能取决于I/O操作的正确顺序,因此需要显式同步
  • 单边操作(RMA)-类似于并行I/O情况,一些RMA场景需要显式同步
  • 共享内存窗口-这些窗口是RMA的子集,在RMA中,对多个列组之间共享内存的访问不通过MPI调用,而是发出直接内存读写指令,这就带来了共享内存编程固有的所有问题,比如可能发生的数据竞争,以及MPI需要锁和屏障
很少有代码真正有意义的情况。根据列组的数量、它们在整个处理元件网络中的分布、要广播的数据的大小、互连的延迟和带宽,以及MPI库实际实现数据分布所使用的算法,由于延迟传播的现象,当列组在时间上甚至稍微不对齐时,可能需要更长的时间来完成,这也可能适用于用户代码本身。这些是病理性病例,通常在特定条件下发生,这就是为什么有时您可能会看到如下代码:

\ifdef UNALIGNED\u BCAST\u慢
MPI_屏障(MPI_通信世界);
#恩迪夫
MPI_Bcast(缓冲区,N,MPI_浮点,0,MPI_通信世界);
甚至

if(配置未对齐\u bcast\u性能\u补救措施)
MPI_屏障(MPI_通信世界);
MPI_Bcast(缓冲区,N,MPI_浮点,0,MPI_通信世界);
我见过至少一个支持MPI的量子化学模拟软件包包含类似的代码

也就是说,MPI中的集体操作不一定是同步的。只有
MPI\u屏障
可以保证在某个时间点所有列组都同时在调用中。MPI允许列组在完成集体操作后提前退出。例如,
MPI_BCAST
可以实现为从根发送的线性序列:

int秩、大小;
MPI_通信等级(通信和等级);
MPI_通信大小(通信和大小);
if(秩==根)
{
对于(int i=0;i

在这种情况下,秩
0
(如果
root
不是
0
)或秩
1
(当
root
0
)将是第一个接收数据的人,并且由于没有更多的通信指向或来自它,因此可以安全地从广播呼叫返回。如果数据缓冲区较大且互连速度较慢,则会在列组之间产生相当大的时间交错。

在广播之前,不需要为正确性设置障碍。也就是说,
MPI\u Bcast()
不执行隐式的
MPI\u Barrier()
任务同步。这些Barrier可能是出于不同的目的添加到那里的,例如测量MPI\u Bcast所用的时间