【发布时间】:2017-01-25 19:31:58
【问题描述】:
MPI_Bcast() 是阻塞还是非阻塞?换句话说,当根发送数据时,是否所有处理器都阻塞,直到每个处理器都接收到该数据?如果没有,如何同步(阻止)所有这些,以便在所有接收到相同数据之前没有人继续。
【问题讨论】:
-
唯一保证同步的 MPI 集体通信调用是
MPI_Barrier。
MPI_Bcast() 是阻塞还是非阻塞?换句话说,当根发送数据时,是否所有处理器都阻塞,直到每个处理器都接收到该数据?如果没有,如何同步(阻止)所有这些,以便在所有接收到相同数据之前没有人继续。
【问题讨论】:
MPI_Barrier。
您需要注意这里的术语,因为 MPI 所指的“阻塞”可能与您在其他上下文中使用的方式不同。
在 MPI 术语中,Bcast 是阻塞的。阻塞意味着,当函数返回时,它已经完成了它应该做的操作。在这种情况下,这意味着在从 Bcast 返回时,保证每个进程中的接收缓冲区都包含您要广播的数据。非阻塞版本是 Ibcast。
在 MPI 术语中,您要问的是操作是否同步,即意味着进程之间的同步。对于像发送这样的点对点操作,这是指发送者在从发送调用返回之前是否等待接收发布。对于集体行动,问题是是否存在障碍(正如@Vladimir 所指出的)。 Bcast 并不一定意味着障碍。
但是,我发布的原因是,在几乎所有使用标准 Send/Recv 调用(而不是单面 Put/Get)编写的 MPI 程序中,您不在乎是屏障之后的同步。每个进程关心的是它是否已经收到了它需要的数据——为什么其他进程在做什么会很重要?如果您随后想与任何其他进程通信,则设计 MPI 例程以便自动发生所需的同步。如果你发出一个接收并且另一个进程很慢,你等待;如果您发出了发送而其他进程没有发出接收,一切仍将正常工作(这是假设您不调用 Rsend - 您应该永远调用 Rsend!)。是否同步对性能有影响,但很少影响程序是否正确。
除非进程通过其他机制进行交互(例如,所有进程都访问同一个文件),否则很难想出一个真正的例子来让你关心 Bcast 是否同步。当然,您总是可以构建一些边缘案例,但在 MPI 的实际应用中,这几乎无关紧要。
许多 MPI 程序都充满了障碍,根据我的经验,它们几乎从来不需要正确性;唯一常见的用例是确保对性能测量进行有意义的计时。
【讨论】:
不,这种阻塞(等待其他进程完成其部分工作)对性能非常不利。每个进程在获得所需的一切后立即继续——这意味着它要接收的数据已经存在,或者要发送的数据至少被复制到某个缓冲区。
如果您需要确保所有进程都已完成,您可以使用MPI_Barrier 来同步进程。如前所述,它可以显着减慢程序的速度。在初始化我的代码时,我只将它用于某些诊断日志记录。不是在实际集成期间。
【讨论】: