MPI中的死锁情况

MPI中的死锁情况,mpi,deadlock,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, 1

我知道死锁通常发生在:
一件事是等待另一件事完成它的工作,而另一件事是等待第一件事完成。 这是我的代码:

    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 );
    }
在文章中,他询问代码是否会造成死锁情况。
这是他的代码:

    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);

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

无论发生什么情况,您的第一块代码都会死锁

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


您提到的“关于MPI的死锁”一文对此进行了很好的解释。它还提供了两种避免死锁的解决方案:(1)正确更改发送和接收的顺序;(2) 使用非阻塞发送和接收。实际上还有第三种避免死锁的方法:可以使用MPI_Sendrecv,这是一种有效的组合发送和接收调用,可以保证不会死锁。

编写一个测试程序,并测试发生了什么。一旦你把死锁编码好,它通常很容易理解;我的意思是,如果程序只有MPI_Recv,它会冻结,因为没有任何东西在发送,我认为这是一个冻结,而不是死锁,关于我指出的那篇文章,我会称之为bug,而不是死锁:)关于这篇文章,我个人认为,如果你在一个进程上开始通信,而不是在另一个进程上,我也会称之为bug。但是,在您最初的案例中,这是死锁的定义。有一个“匹配的”发送/接收对,但它们的顺序不正确,因此我们最终让两个进程都等待另一个进程进入匹配的通信调用。我不完全理解你的第三种情况。