2010-01-07 51 views
3

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

进程0:

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

流程1:

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

交付在他们被送了以处理1的信息,即我可以确定in1 == stuff1和in2 == stuff2 如果使用的标签在所有情况下都是相同的

回答

6

是的,这些消息按照它们发送的顺序接收。这被标准描述为非超车信息。看到这个MPI Standard section了解详情,以下是摘录:

订单消息是不超车:如果发件人发送两个消息相继到同一目的地,并且都匹配相同的接收,则该操作无法接收第二条消息,如果第一条消息仍然未决。如果接收者连续发送两个接收者,并且两者都匹配相同的消息,则如果第一个接收操作仍然未决,则第二个接收操作不能被该消息满足。这个要求有利于发送到接收方的匹配。它保证消息传递代码是确定性的,如果进程是单线程的,并且通配符MPI_ANY_SOURCE未用于接收。 (稍后描述的一些呼叫,例如MPI_CANCEL或MPI_WAITANY,是非确定性的附加来源。)

2

是和否。

我可以肯定的是IN1 == stuff1和 平方英寸== stuff2如果所使用的标签是 在所有情况下一样的吗?

是的。 send和recv之间有一个确定的1:1相关性,它将正确的输入到正确的recv缓冲区中。此行为由标准保证,并由所有MPI实施强制执行。

号内部消息进展,并且其中在接收器侧被填充缓冲器的确切顺序的确切次序是有点的黑箱....尤其与多个RDMA式消息传输在飞行缓冲器正在时使用(例如InfiniBand)。

如果您的代码使用多个线程并检查缓冲区以确定完整性(例如等待某个位切换)而不是使用MPI_Test或MPI_Wait,则可能消息可能无序到达(但在正确的缓冲区中)。

如果您的代码依赖于正在填充的in1 = stuff1 BEFORE in2 = stuff2填充在接收端,并且这两个消息都有一个发送级别,则使用MPI_Issend(非阻塞,同步发送)将会保证邮件按顺序收发。如果需要保证来自多个发送队列的多个recv的缓冲区填充顺序,则每个revc之间需要某种阻塞调用(例如,MPI_Recv,MPI_Barrier,MPI_Wait等)。

+0

必须-1,因为我不能相信你的“是”和“否”答案中的“否”部分......用你在那里建议的方式“检查完成”是很荒唐的。等价地,如果我问你“是否是x = 42; printf(”%d“,x);'保证打印42?你可以说“是,否,否则,因为如果你是通过调试器进行单步调试,并改变了'x'的值,那么它就不会。” – 2010-03-28 06:41:22

+2

@j ...描述的情况发生在我支持的三个不同的用户身上。他们的工作具有多线程级别,只有一个MPI通信线程。其他线程正在与硬件控制器交互。硬件控制器线程正在检查缓冲区的最后一位以确定消息完成。当他们从TCP移动到IB时,显示了无序的消息到达问题。这更像是一个“编译器优化”,而不是你给出的调试器例子。结构管理器保存缓冲区顺序,但优化了实际的传输顺序。 – 2010-03-29 15:47:55

+0

好吧,我惊呆了。 (这就是MPI_Test()用于*!)但是,如果3个用户得到了这个错误,那么你的帖子中的信息是有价值的,所以如果你编辑它来添加一个大声的“但不要做这个,它是愚蠢的”或有些,我会+1。 – 2010-04-02 10:49:58