MPI中的死锁情况

时间:2015-11-09 08:41:29

标签: mpi deadlock

我知道在以下情况下会发生死锁:
有一件事是等待另一件事来完成它的工作,而另一件事是等待第一件事完成。 这是我的代码:

    MPI_Comm_rank(MPI_COMM_WORLD, &myrank); /* Get rank */
    if( myrank == 0 ) {
    MPI_Recv( b, 100, MPI_DOUBLE, 1, 19, MPI_COMM_WORLD, &status );
    MPI_Send( a, 100, MPI_DOUBLE, 1, 17, MPI_COMM_WORLD );
    }
    else if( myrank == 1 ) {
    MPI_Recv( b, 100, MPI_DOUBLE, 0, 17, MPI_COMM_WORLD, &status );
    MPI_Send( a, 100, MPI_DOUBLE, 0, 19, MPI_COMM_WORLD );
    }

在文章Deadlock with MPI中,他询问代码是否出现死锁情况。
这是他的代码:

    MPI_Comm_rank (comm, &my_rank);
    if (my_rank == 0) {
       MPI_Send (sendbuf, count, MPI_INT, 1, tag, comm);
       MPI_Recv (recvbuf, count, MPI_INT, 1, tag, comm, &status);
    } else if (my_rank == 1) {
       MPI_Send (sendbuf, count, MPI_INT, 0, tag, comm);
       MPI_Recv (recvbuf, count, MPI_INT, 0, tag, comm, &status);
    }

嗯,该程序可能会冻结,但其情况并未被视为死锁情况。如果我们认为它是一个死锁情况,那么下面的情况呢:

    MPI_Recv (recvbuf, count, MPI_INT, 1, tag, comm, &status);

该计划也将冻结。我写了一篇关于死锁情况的文章,我很困惑。

1 个答案:

答案 0 :(得分:0)

无论如何,你的第一段代码都将陷入僵局。

第二个代码块的行为取决于许多因素,例如MPI实现,消息大小和MPI运行时配置。这里的基本思想是阻塞MPI_Send例程只有在可以安全地覆盖发送缓冲区时才会返回。离开发送缓冲区的数据可以直接进入目标进程,也可以复制到某个中间缓冲区空间。如果前者是真的,你的代码就会死锁。否则,您的代码可能看起来效果不错,但在将代码移植到其他系统时可能会遇到问题。

与MPI的僵局'你提到的文章很好地解释了这一点。它还提供了两种避免死锁的解决方案:(1)改变发送和接收的顺序; (2)使用非块发送和接收。实际上有第三种方法可以避免死锁:你可以使用MPI_Sendrecv,这实际上是一个组合的发送和接收调用,保证不会死锁。