3

我正在使用 MPI(使用 fortran,但问题比任何给定语言更具体到 MPI 标准),特别是使用缓冲的发送/接收函数 isend 和 irecv。现在,如果我们想象以下场景:

进程0:

isend(stuff1, ...)
isend(stuff2, ...)

过程1:

wait 10 seconds
irecv(in1, ...)
irecv(in2, ...)

消息是否按照发送顺序传递到进程 1,即如果使用的标签在所有情况下都相同,我可以确定 in1 == stuff1 和 in2 == stuff2吗?

4

2 回答 2

7

是的,消息按发送顺序接收。这被标准描述为非超车消息。有关详细信息,请参阅此MPI 标准部分 ,以下是摘录:

Order Messages are non-overtaking:如果一个发送者连续发送两个消息到同一个目的地,并且都匹配同一个接收,那么如果第一个消息仍然是未决的,那么这个操作就不能接收第二个消息。如果接收者连续发布两个接收,并且都匹配相同的消息,那么如果第一个仍然未决,则该消息不能满足第二个接收操作。此要求有助于发送与接收的匹配。它保证消息传递代码是确定性的,如果进程是单线程的并且通配符 MPI_ANY_SOURCE 未在接收中使用。(稍后描述的一些调用,例如 MPI_CANCEL 或 MPI_WAITANY,是不确定性的额外来源。)

于 2010-01-08T09:06:44.793 回答
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 等)。

于 2010-02-22T16:41:18.503 回答