我什么时候需要使用MPI_Barrier()?

Jie*_*eng 28 synchronization mpi openmpi

我想知道什么时候需要使用屏障?例如,在分散/聚集之前/之后我需要它吗?或者OMPI应该确保在分散/收集之前所有进程都已达到这一点?同样,在广播之后我可以期望所有进程都已收到消息吗?

Mar*_*ayr 25

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

还请注意,MPI_Barrier不会神奇地等待非阻塞呼叫.如果您使用非阻塞发送/接收,并且两个进程在发送/接收对之后在MPI_Barrier处等待,则无法保证进程在MPI_Barrier之后发送/接收所有数据.请改用MPI_Wait(和朋友).所以下面的代码包含错误:

/* ERRORNOUS CODE */

Code for Process 0:
Process 0 sends something using MPI_Isend
MPI_Barrier(MPI_COMM_WORLD);
Process 0 uses buffer passed to MPI_Isend // (!)

Code for Process 1:
Process 1 recvs something using MPI_Irecv
MPI_Barrier(MPI_COMM_WORLD);
Process 1 uses buffer passed to MPI_Irecv // (!)
Run Code Online (Sandbox Code Playgroud)

(!)有的两条线都不安全!

MPI_Barrier仅在少数情况下有用.大多数情况下,您不关心您的进程是否同步.更好地了解阻塞和非阻塞调用!

  • 我已经稍微更新了你的答案,因为MPI-3.0引入了非阻塞集体. (3认同)
  • @JiewMeng MPI在调用MPI_Isend后不能立即从缓冲区中读取.如果你在`(!)`改变它,你可能会发送不同的东西.我不太确定,但我认为在这种情况下这种行为是不确定的. (2认同)

Edr*_*ric 16

MPI_Barrier例如,一种用途是控制对诸如文件系统之类的外部资源的访问,该外部资源不是使用MPI访问的.例如,如果您希望每个进程按顺序将内容写入文件,您可以这样做:

int rank, size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
for ( int ii = 0; ii < size; ++ii ) {
    if ( rank == ii ) {
        // my turn to write to the file
        writeStuffToTheFile();
    }
    MPI_Barrier(MPI_COMM_WORLD);
}
Run Code Online (Sandbox Code Playgroud)

这样,您可以确保没有两个进程同时调用writeStuffToTheFile.