gpt4 book ai didi

c++ - Microsft MPI MPI_Isend 中的死锁

转载 作者:行者123 更新时间:2023-11-28 00:07:05 24 4
gpt4 key购买 nike

我有以下带有 Microsoft MPI 的 c/c++ 代码

#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
int main (int argc, char *argv[])
{
int err, numtasks, taskid;
int out=0,val;
MPI_Status status;
MPI_Request req;

err=MPI_Init(&argc, &argv);
err=MPI_Comm_size(MPI_COMM_WORLD, &numtasks);
err=MPI_Comm_rank(MPI_COMM_WORLD, &taskid);


int receiver=(taskid+1)% numtasks;
int sender= (taskid-1+numtasks)% numtasks;
printf("sender %d, receiver %d, rank %d\n",sender,receiver, taskid);

val=50;
MPI_Isend(&val, 1, MPI_INT, receiver, 1, MPI_COMM_WORLD, &req);
MPI_Irecv(&out, 1, MPI_INT, sender, 1, MPI_COMM_WORLD, &req);
printf ("Rank: %d , Value: %d\n", taskid, out );
err=MPI_Finalize();
return 0;
}

如果启动超过 2 个进程,应用程序将进入死锁状态。使用 2 个进程,应用程序可以工作,但不会执行“out”上的写操作。此代码适用于 linux mpi 发行版,问题似乎只出现在 Microsoft 版本中。有什么帮助吗?

最佳答案

首先,每个 MPI 进程执行两次通信:一次发送和一次接收。因此,您需要存储两个请求 (MPI_Request req[2]) 和两个状态检查 (MPI_Status status[2])。

其次,您需要在调用非阻塞发送/接收之后等待,以确保它们正确完成。

MPI_Isend(&val, 1, MPI_INT, receiver, 1, MPI_COMM_WORLD, &req[0]);
MPI_Irecv(&out, 1, MPI_INT, sender, 1, MPI_COMM_WORLD, &req[1]);

// While the communication is happening, here you can overlap computation
// on data that is NOT being currently communicated, with the communication of val/out

MPI_Waitall(2, req, status);

// Now both the send and receive have been finished for this process,
// and we can access out, assured that it is valid

printf ("Rank: %d , Value: %d\n", taskid, out);

至于为什么这适用于 Linux 发行版,而不是 Microsoft 发行版......我只能假设 Linux 实现在底层有效地将非阻塞通信实现为阻塞通信。也就是说,他们在“欺骗”并在您应该完成之前完成您的通信。这使他们更容易,因为他们不必跟踪关于通信的尽可能多的信息,但它也破坏了您重叠计算和通信的能力。你不应该依赖它来工作。

关于c++ - Microsft MPI MPI_Isend 中的死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35018921/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com