我使用MPI_Probe动态发送消息(接收方不知道所发送消息的大小)。我的代码看起来有点像-
if (world_rank == 0) {
int *buffer = ...
int bufferSize = ...
MPI_Send(buffer, buffersize, MPI_INT, 1, 0, MPI_COMM_WORLD);
} else if (world_rank == 1) {
MPI_Status status;
MPI_Probe(0, 0, MPI_COMM_WORLD, &status);
int count = -1;
MPI_Get_count(&status, MPI_INT, &count);
int* buffer = (int*)malloc(sizeof(int) * count);
MPI_Recv(buffer, count, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}如果我在多个线程中运行这段代码,那么由于调度程序将线程交织在一起,是否有可能在一个线程中调用MPI_Probe,而在另一个线程中调用MPI_recv。本质上,是上述代码线程安全。
发布于 2015-03-27 17:56:38
首先,默认情况下,MPI并不是线程安全的。您必须检查您的特定库是否已经编译好以确保线程安全,然后使用MPI_Init_thread而不是MPI_Init初始化MPI。
假设您的MPI实例是为线程安全例程初始化的,则由于您已经确定的争用条件,您的代码仍然不是线程安全的。
在多线程环境中,MPI_Probe和MPI_Recv的配对不是线程安全的,这是MPI-2:size-mpi3.pdf中已知的问题。
至少有两种可能的解决办法。您可以使用MPI-3 MPI_Mprobe和MPI_MRecv,也可以在关键代码周围使用锁/互斥锁。这可以如下所示:
MPI-2解决方案(使用互斥锁):
int number_amount;
if (world_rank == 0) {
int *buffer = ...
int bufferSize = ...
MPI_Send(buffer, buffersize, MPI_INT, 1, 0, MPI_COMM_WORLD);
} else if (world_rank == 1) {
MPI_Status status;
int count = -1;
/* aquire mutex/lock */
MPI_Probe(0, 0, MPI_COMM_WORLD, &status);
MPI_Get_count(&status, MPI_INT, &count);
int* buffer = (int*)malloc(sizeof(int) * count);
MPI_Recv(buffer, count, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
/* release mutex/lock */
}MPI-3解决方案
int number_amount;
if (world_rank == 0) {
int *buffer = ...
int bufferSize = ...
MPI_Send(buffer, buffersize, MPI_INT, 1, 0, MPI_COMM_WORLD);
} else if (world_rank == 1) {
MPI_Status status;
MPI_Message msg;
int count = -1;
MPI_Mprobe(0, 0, MPI_COMM_WORLD, &msg, &status);
MPI_Get_count(&status, MPI_INT, &count);
int* buffer = (int*)malloc(sizeof(int) * count);
MPI_Mrecv(buffer, count, MPI_INT, &msg, MPI_STATUS_IGNORE);
}https://stackoverflow.com/questions/29305842
复制相似问题