MPI_Recv是否可能收到标签不匹配的消息?
我的逻辑:MPI_Isend / MPI_Recv通讯。
节点1 Isend带有标签0的消息,然后Isend另一条带有标签1的消息,因为节点1中有两个线程,因此Isend动作可能同时发生。
节点2将探测是否有来自节点1的消息,如果是,则接收该消息。
在我的设计中,我希望节点2接收带有标签0的消息,然后标记1.但是当节点2探测到消息来自节点1的信号时,它收到的消息长度与节点1相同。标记1消息。然后没有来自节点1的消息。似乎标签0消息丢失了。
我很困惑,期待一些答案。
答案 0 :(得分:2)
MPI不能丢失消息,除非它们以“就绪”模式发送,即使用MPI_Rsend
或MPI_Irsend
,而接收方尚未就绪,这显然不是你的情况。 MPI_Isend
启动发送操作,但除非进度完成,否则无法保证完成。许多MPI调用导致非阻塞操作正在进行,但最明确的操作是MPI_Wait
及其变体。还有MPI实现具有特殊的进程线程,可以在后台进行非阻塞操作(例如,Open MPI可以通过这种方式编译)。
如果第二个消息非常小并且正在使用不同的发送模式(例如一些急切的发送协议),则第二个消息可能在第一个消息之前到达。 MPI仅保证具有相同信封的消息按顺序保留。消息信封是元组(发送者,接收者,标签,通信者)。
你也谈到从不同的线程发送消息。您确定您的MPI库是线程安全的,并且您使用MPI_THREAD_MULTIPLE
级别的线程支持对其进行了初始化,例如:
int provided;
MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
if (provided != MPI_THREAD_MULTIPLE)
{
printf("Sorry, your MPI library does not provide MPI_THREAD_MULTIPLE\n");
MPI_Abort(MPI_COMM_WORLD, 0);
}
答案 1 :(得分:0)
您最好的选择是让接收方为标记0发布MPI_IRecv
,然后为标记1发布MPI_IRecv
。然后等待,直到消息使用MPI_Wait*
进入,这可能是MPI_WaitAll
,MPI_WaitAny
或MPI_Wait
取决于接下来需要发生的事情。
通过这种方式,你有两个接听电话正在等待消息,标记的消息就会到达应该去的地方。