为什么这个 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 会分配一定大小的接收缓冲区,以捕获较小的接收,例如您发送的单个整数。
为什么这个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 会分配一定大小的接收缓冲区,以捕获较小的接收,例如您发送的单个整数。