在收到消息之前,必须进行多次MPI_Iprobe

在收到消息之前,必须进行多次MPI_Iprobe,mpi,openmpi,Mpi,Openmpi,我正在使用的应用程序涉及多个处理类似任务的进程,并且只是偶尔共享信息。我有一个使用openMPI的工作实现,但有时收到的消息比发送的消息晚得多,这使我遇到了问题 此时,每个进程的主循环首先处理任何等待的消息,然后进行一系列计算,然后使用MPI_ISend将结果发送到其他每个进程。比如: while problem is unsolved: bool flag; MPI_Iprobe(MPI_ANY_SOURCE, ..., &flag, MPI_IGNORE_STATUS);

我正在使用的应用程序涉及多个处理类似任务的进程,并且只是偶尔共享信息。我有一个使用openMPI的工作实现,但有时收到的消息比发送的消息晚得多,这使我遇到了问题

此时,每个进程的主循环首先处理任何等待的消息,然后进行一系列计算,然后使用MPI_ISend将结果发送到其他每个进程。比如:

while problem is unsolved:
  bool flag;
  MPI_Iprobe(MPI_ANY_SOURCE, ..., &flag, MPI_IGNORE_STATUS);
  while flag:
    MPI_Recv(&message, ...);
    // update local information based on message contents
    MPI_Iprobe(MPI_ANY_SOURCE, ..., &flag, MPI_IGNORE_STATUS);

  result = doComputation(); // between 2s and 1m

  MPI_Request request;
  for dest in other_processes:
    MPI_Isend(result, ..., dest, &request);
    MPI_Wait(&request, MPI_STATUS_IGNORE); // Doesn't seem to make any difference 
这可以正常工作,但以下问题经常发生:进程X发送消息,但下一次进程Y探测时,它找不到消息。通常,只有一个或两个循环(以及许多秒)之后,进程Y才会收到进程X发送的消息。消息最终总是会通过,但进程Y不必等到第二次或第三次探测时才真正收到消息

我对MPI的工作原理没有深入的了解,但通过阅读其他问题,我认为问题与MPI没有机会处理消息有关,因为在我的程序中,MPI函数只是偶尔调用,而不是在一个紧密的循环中调用。为了给MPI留出一些额外的时间,我向Iprobe添加了几个虚拟调用:

bool flag;
MPI_Iprobe(MPI_ANY_SOURCE, ..., &flag, MPI_IGNORE_STATUS);
MPI_Iprobe(MPI_ANY_SOURCE, ..., &flag, MPI_IGNORE_STATUS);
MPI_Iprobe(MPI_ANY_SOURCE, ..., &flag, MPI_IGNORE_STATUS);
MPI_Iprobe(MPI_ANY_SOURCE, ..., &flag, MPI_IGNORE_STATUS);
while flag:
  MPI_Recv(&message, ...);
  // update local information based on message contents
  MPI_Iprobe(MPI_ANY_SOURCE, ..., &flag, MPI_IGNORE_STATUS);
它是有效的——任何发送的消息总是在下一次进程探测它们时被接收

但这是丑陋的,我怀疑它可能会在不同的平台上产生不同的结果。那么,在探测之前,是否有其他方法允许MPI有一些时间来完成消息进程?我不想在没有探测的情况下使用阻塞接收,因为进程Y应该能够在没有消息等待的情况下继续计算


谢谢。

它的工作原理与MPI标准中的广告相同。一次调用
MPI_Iprobe
几乎永远不够。它应该用于繁忙的等待循环中。正确进行操作所需的调用数量取决于具体的实现。因此,有没有办法在MPI中执行偶尔的消息检查?方法是使用
MPI\u Iprobe
。只是不要期望它立即返回true,并相应地设计您的算法,例如,当循环未处理任何消息时,减少计算量,并在
docompution
函数内定期调用非阻塞探测函数,以实现正确的进程。