我正在使用MPI(使用fortran,但问题是MPI标准比任何给定语言更具体),特别是使用缓冲的发送/接收函数isend和irecv。现在,如果我们想象以下情况:
流程0:
isend(stuff1, ...)
isend(stuff2, ...)
流程1:
wait 10 seconds
irecv(in1, ...)
irecv(in2, ...)
消息是按照发送的顺序发送到进程1的,即我是否可以确定in1 == stuff1和in2 == stuff2 如果使用的标签在所有情况下都相同?
答案 0 :(得分:7)
是的,邮件按发送顺序收到。这被标准描述为非超车消息。有关详细信息,请参阅此MPI Standard section,此处摘录如下:
订单消息是非超车的:如果发件人连续向同一目的地发送两条消息,并且两者都匹配相同的接收,则如果第一条消息仍处于未决状态,则此操作无法接收第二条消息。如果接收器连续发布两个接收,并且两者都匹配相同的消息,则如果第一个消息仍然未决,则该消息不能满足第二个接收操作。此要求有助于发送与接收的匹配。如果进程是单线程的并且未在接收中使用通配符MPI_ANY_SOURCE,则它保证消息传递代码是确定性的。 (稍后描述的一些调用,例如MPI_CANCEL或MPI_WAITANY,是非确定性的其他来源。)
答案 1 :(得分:1)
是和否。
我可以确定in1 == stuff1和 in2 == stuff2如果使用的标签是 在所有情况下都一样吗?
是。 send和recv之间存在确定性的1:1相关性,可以将正确的输入输入正确的recv缓冲区。此行为由标准保证,并由所有MPI实现强制执行。
没有。内部消息进展的确切顺序以及接收器侧缓冲区的确切顺序在某种程度上是一个黑盒子......尤其是在使用具有多个正在进行的缓冲区的RDMA样式消息传输时(例如InfiniBand)。
如果您的代码使用多个线程,并检查缓冲区以确定完整性(例如,等待切换的位)而不是使用MPI_Test或MPI_Wait,那么消息可能无序到达(但是正确的缓冲区)。
如果您的代码依赖于in1 = stuff1正在填充,则在in2 = stuff2填充在接收方,并且两个消息都有一个发送等级,那么使用MPI_Issend(非阻塞,同步发送)将保证消息按顺序收回。如果需要保证来自多个发送等级的多个recv的缓冲器群顺序,则每个revc之间需要某种阻塞调用(例如MPI_Recv,MPI_Barrier,MPI_Wait等)。