我无法理解MPI_Send()
和MPI_Isend()
与MPI_Wait()
之间的区别。
当我们在MPI_Wait()
之后使用MPI_Isend()
时,不是这样吗?我们将其转换为阻塞调用吗?因为我们必须等到所有的元素都被复制到缓冲区中。
我知道这种配置(如下所示)可能会导致死锁。
P1--> MPI_Send() MPI_Recv()
P2--> MPI_Send() MPI_Recv()
但是,这种配置(如下所示)是否也会导致死锁?
P1--> MPI_Isend() MPI_Wait() MPI_Recv()
P2--> MPI_Isend() MPI_Wait() MPI_Recv()
发布于 2021-02-14 09:34:22
TL;DR:您需要使用MPI_Wait
(或使用测试来测试请求的完成),以确保消息已经完成,并且可以再次安全地操作发送/接收缓冲区中的数据。
更详细的答案
开始非阻塞发送 int MPI_Isend(const *buf,int计数,MPI_Datatype数据类型,int dest,int标记,MPI_Comm comm,MPI_Request *请求)
假设您使用MPI_Isend
发送了一个MPI_Isend
数组,而没有调用MPI_Wait
;在这种情况下,您不太确定什么时候可以安全地修改(或释放该数组的内存)。这同样适用于MPI_Irecv
。然而,调用MPI_Wait
可以确保从那时起,有一种情况是读/写(或释放内存)缓冲区,而不存在未定义行为或不一致数据的风险。
在MPI_Isend
期间,必须读取和发送缓冲区的内容(例如,int
的数组);在MPI_Irecv
期间,接收缓冲区的内容必须到达。同时,可以将某些计算与正在进行的过程重叠,但是此计算不能更改(或读取)发送/recv缓冲区的争用。然后调用MPI_Wait
,以确保从那时起数据发送/recv可以安全地读取/修改,不会出现任何问题。
我无法理解MPI_Send()和MPI_Isend()与MPI_Wait()之间的区别。
从这个所以螺纹可以读到:
在通信完成之前,这些函数不会返回(即阻塞)。稍微简化一下,这意味着可以重用传递给MPI_Send()的缓冲区,因为MPI将其保存在某个地方,或者因为它已被目的地接收。
最后:
我知道这种配置(如下所示)可能导致死锁P1-> MPI_Send() MPI_Recv() P2-> MPI_Send() MPI_Recv(),但是这种配置(如下所示)也会导致死锁吗?P1-> MPI_Isend() MPI_Wait() MPI_Recv() P2-> MPI_Isend() MPI_Wait() MPI_Recv()
如果消息的交换只发生在进程P1
和P2
之间,那么是的。Semantically --对MPI_Isend(
的调用),然后调用MPI_Wait()
,与调用MPI_Send()
相同。
P1
向P2
发送消息并等待该消息的完成,但是P2
向P1
发送消息并等待消息的完成。由于每个进程都在等待,这将导致死锁。
发布于 2021-02-14 08:29:46
当您使用MPI_Isend
+ MPI_Wait
时,您可以将通信与计算重叠:
MPI_Isend(...) // Non blocking send
// Perform computation here (make sure you don't use the buffer you're sending!)
MPI_Wait(...)
上面,当您的数据被发送到收件人时,MPI_Isend下面的代码将执行(因为MPI_Isend是非阻塞的)。这允许您在通信发生时进行计算。与此不同的是,MPI_Send()
是不同的,因为它是阻塞的,因此在通信发生时不能执行计算,就像上面使用MPI_Isend和MPI_Wait的代码一样。
https://stackoverflow.com/questions/66193529
复制相似问题