MPI_Send() 和 MPI_Isend() 后跟 MPI_Wait() 有什么区别?
What is the difference between MPI_Send() and MPI_Isend() followed by MPI_Wait()?
我无法理解 MPI_Send()
和 MPI_Isend()
后跟 MPI_Wait()
之间的区别。
当我们在 MPI_Isend()
之后使用 MPI_Wait()
时,我们不是在将其变成阻塞调用吗?因为我们必须等到所有元素都复制到缓冲区中。
我知道这个配置(下面给出)可能会导致死锁
P1--> MPI_Send() MPI_Recv()
P2--> MPI_Send() MPI_Recv()
但是这个配置(下面给出)也会导致死锁吗?
P1--> MPI_Isend() MPI_Wait() MPI_Recv()
P2--> MPI_Isend() MPI_Wait() MPI_Recv()
当您使用 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.
TL;DR: 您需要使用MPI_Wait
(或使用MPI_Test来测试请求是否完成)以确保消息已完成,send/receive 缓冲区中的数据可以再次安全 操作。
更详细的回答:
Begins a nonblocking send
int MPI_Isend(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request)
让我们想象一下,您使用 MPI_Isend
发送一个 int
的数组而不调用 MPI_Wait
;在这种情况下,您不确定何时可以 安全地 修改(或释放该数组的内存)。 MPI_Irecv
也是如此。尽管如此,调用 MPI_Wait
可确保从那一点开始 read/write (或释放内存)缓冲区没有 undefined behavior 或不一致数据的风险。
在MPI_Isend
期间缓冲区的内容(例如,int
s的数组)必须被读取和发送;同样,在 MPI_Irecv
期间,接收缓冲区的内容必须到达。同时,可以将一些计算与正在进行的过程重叠,但是此计算无法更改(或读取)send/recv 缓冲区 的内容。然后调用 MPI_Wait
以确保从那时起数据 send/recv 可以安全地 read/modified 没有任何问题。
I am not able to understand the difference between MPI_Send() and
MPI_Isend() followed by MPI_Wait().
从这个SO Thread可以读到:
These functions do not return (i.e., they block) until the
communication is finished. Simplifying somewhat, this means that the
buffer passed to MPI_Send() can be reused, either because MPI saved it
somewhere, or because it has been received by the destination.
最后:
I know that this configuration(given below) may lead to a deadlock
P1--> MPI_Send() MPI_Recv()
P2--> MPI_Send() MPI_Recv()
But can this configuration(given below) also lead to deadlock?
P1--> MPI_Isend() MPI_Wait() MPI_Recv()
P2--> MPI_Isend() MPI_Wait() MPI_Recv()
如果消息交换仅发生在进程 P1
和 P2
之间,那么可以。 语义上 调用 MPI_Isend(
) 然后调用 MPI_Wait()
与调用 MPI_Send()
.
相同
P1
向 P2
发送消息并等待该消息完成,但是 P2
向 P1
发送消息并等待。因为,每个进程都在等待对方,这会导致死锁。
我无法理解 MPI_Send()
和 MPI_Isend()
后跟 MPI_Wait()
之间的区别。
当我们在 MPI_Isend()
之后使用 MPI_Wait()
时,我们不是在将其变成阻塞调用吗?因为我们必须等到所有元素都复制到缓冲区中。
我知道这个配置(下面给出)可能会导致死锁
P1--> MPI_Send() MPI_Recv()
P2--> MPI_Send() MPI_Recv()
但是这个配置(下面给出)也会导致死锁吗?
P1--> MPI_Isend() MPI_Wait() MPI_Recv()
P2--> MPI_Isend() MPI_Wait() MPI_Recv()
当您使用 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.
TL;DR: 您需要使用MPI_Wait
(或使用MPI_Test来测试请求是否完成)以确保消息已完成,send/receive 缓冲区中的数据可以再次安全 操作。
更详细的回答:
Begins a nonblocking send
int MPI_Isend(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request)
让我们想象一下,您使用 MPI_Isend
发送一个 int
的数组而不调用 MPI_Wait
;在这种情况下,您不确定何时可以 安全地 修改(或释放该数组的内存)。 MPI_Irecv
也是如此。尽管如此,调用 MPI_Wait
可确保从那一点开始 read/write (或释放内存)缓冲区没有 undefined behavior 或不一致数据的风险。
在MPI_Isend
期间缓冲区的内容(例如,int
s的数组)必须被读取和发送;同样,在 MPI_Irecv
期间,接收缓冲区的内容必须到达。同时,可以将一些计算与正在进行的过程重叠,但是此计算无法更改(或读取)send/recv 缓冲区 的内容。然后调用 MPI_Wait
以确保从那时起数据 send/recv 可以安全地 read/modified 没有任何问题。
I am not able to understand the difference between MPI_Send() and MPI_Isend() followed by MPI_Wait().
从这个SO Thread可以读到:
These functions do not return (i.e., they block) until the communication is finished. Simplifying somewhat, this means that the buffer passed to MPI_Send() can be reused, either because MPI saved it somewhere, or because it has been received by the destination.
最后:
I know that this configuration(given below) may lead to a deadlock
P1--> MPI_Send() MPI_Recv()
P2--> MPI_Send() MPI_Recv()
But can this configuration(given below) also lead to deadlock?
P1--> MPI_Isend() MPI_Wait() MPI_Recv()
P2--> MPI_Isend() MPI_Wait() MPI_Recv()
如果消息交换仅发生在进程 P1
和 P2
之间,那么可以。 语义上 调用 MPI_Isend(
) 然后调用 MPI_Wait()
与调用 MPI_Send()
.
P1
向 P2
发送消息并等待该消息完成,但是 P2
向 P1
发送消息并等待。因为,每个进程都在等待对方,这会导致死锁。