为什么这个 MPI_Bcast 相关代码没有死锁?

why this MPI_Bcast related code not deadlock?

为什么这个mpi代码没有出现死锁?

int main(int argc, char *argv[])
{
        int rank,size;

        MPI_Init(&argc, &argv);
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);
        MPI_Comm_size(MPI_COMM_WORLD, &size);

        if(2!=size) MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
        int buf1, buf2;
        buf1 = 1;
        buf2 = 1;
        if (0==rank) {
            MPI_Bcast(&buf1,1,MPI_INT,0,MPI_COMM_WORLD);
            MPI_Bcast(&buf2,1,MPI_INT,1,MPI_COMM_WORLD);
            printf("proc 0 done\n");
        }
        if (1==rank) {
            MPI_Bcast(&buf2,1,MPI_INT,1,MPI_COMM_WORLD);
            MPI_Bcast(&buf1,1,MPI_INT,0,MPI_COMM_WORLD);
            printf("proc 1 done\n");
        }
        MPI_Finalize();
}

结果是:

proc 0 完成

proc 1 完成。

考虑代码的以下死锁变体:

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

int main(int argc, char *argv[])
{
        int rank,size;

        MPI_Init(&argc, &argv);
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);
        MPI_Comm_size(MPI_COMM_WORLD, &size);



        if(2!=size) MPI_Abort(MPI_COMM_WORLD, 1);

    int* buf1 = (int*)malloc(sizeof(int) * 10000);
    int* buf2 = (int*)malloc(sizeof(int) * 10000);

        buf1[0] = 1;
        buf2[0] = 1;
        if (0==rank) {
            MPI_Bcast(buf1,10000,MPI_INT,0,MPI_COMM_WORLD);
            MPI_Bcast(buf2,10000,MPI_INT,1,MPI_COMM_WORLD);
            printf("proc 0 done\n");
        }
        if (1==rank) {
            MPI_Bcast(buf2,10000,MPI_INT,1,MPI_COMM_WORLD);
            MPI_Bcast(buf1,10000,MPI_INT,0,MPI_COMM_WORLD);
            printf("proc 1 done\n");
        }
        MPI_Finalize();
}

唯一的变化是将通信字节数增加了 10000 倍。为什么这会导致代码死锁?

查看 MPI 文档的 communication modes 部分。发送可以 return 成功,如果 a) 有一个接收在接收队列上等待或 b) 接收队列分配了足够大小的接收缓冲区。

默认情况下,MPI 会分配一定大小的接收缓冲区,以捕获较小的接收,例如您发送的单个整数。