MPI_SEND在MPI_BARRIER之后停止工作

时间:2012-05-05 21:25:10

标签: webserver mpi distributed send barrier

我正在使用C / MPI构建分布式Web服务器,在我的代码中第一个MPI_BARRIER之后,点对点通信似乎完全停止工作。标准C代码在屏障之后工作,所以我知道每个线程都通过屏障。在屏障之前,点对点通信也可以正常工作。但是,当我将屏障之前处理线路的相同代码复制粘贴到屏障之后的线路时,它会完全停止工作。 SEND将永远等待。当我尝试使用ISEND时,它会通过该行,但永远不会收到消息。我一直在谷歌上搜索这个问题,每个遇到MPI_BARRIER问题的人都被告知屏障工作正常并且他们的代码是错误的,但我不能为我的生活弄清楚为什么我的代码是错误的。可能导致这种行为的原因是什么?

以下示例程序演示了这一点:

#include <mpi.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
  int procID;
  int val;
  MPI_Status status;

  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &procID);
  MPI_Barrier(MPI_COMM_WORLD);

  if (procID == 0)
  {
    val = 4;
    printf("Before send\n");
    MPI_Send(&val, 1, MPI_INT, 1, 4, MPI_COMM_WORLD);
    printf("after send\n");
  }

  if (procID == 1)
  {
    val = 1;
    printf("before: val = %d\n", val);
    MPI_Recv(&val, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
    printf("after: val = %d\n", val);
  }

  MPI_Finalize();
  return 0;
}

在屏障之前移动两个if语句会导致此程序正常运行。

编辑 - 看来第一次通信无论何种类型都有效,并且所有未来的通信都会失败。这比我最初想的要宽泛得多。如果第一次通信是障碍或其他消息,将来通信无法正常工作,这无关紧要。

1 个答案:

答案 0 :(得分:5)

当使用TCP / IP进行通信时,Open MPI具有已知功能:它尝试使用处于“UP”状态的所有配置的网络接口。如果通过所有这些接口无法访问某些其他节点,则会出现问题。这是Open MPI采用的贪婪通信优化的一部分,有时候,就像你的情况一样,会导致问题。

似乎至少第二个节点有多个接口已启动,并且在协商阶段将此事实引入第一个节点:

  • 一个配置为128.2.100.167
  • 一个配置为192.168.109.1(您是否在计算机上运行了隧道或Xen?)

屏障通信在第一个网络上发生,然后下一个MPI_Send尝试通过第二个网络发送到第二个地址,这显然不会连接所有节点。

最简单的解决方案是告诉Open MPI只使用连接节点的nework。您可以使用以下MCA参数告诉它:

--mca btl_tcp_if_include 128.2.100.0/24

(或任何您的通讯网络)

如果所有计算机上的网络接口相同,也可以指定网络接口列表,例如

--mca btl_tcp_if_include eth0

或者您可以告诉Open MPI专门排除某些接口(但是如果您这样做,则必须始终告诉它排除环回“lo”):

--mca btl_tcp_if_exclude lo,virt0

希望能帮助你和许多其他人在这里出现同样的问题。看起来最近几乎所有Linux发行版都默认启动了各种网络接口,这可能会导致Open MPI出现问题。

P.S。请将这些节点放在防火墙后面!