我无法理解在MPI阻止通信和非阻塞通信的概念。 什么是两者之间的区别是什么? 有哪些优势和劣势?
谢谢!
我无法理解在MPI阻止通信和非阻塞通信的概念。 什么是两者之间的区别是什么? 有哪些优势和劣势?
谢谢!
阻断通信用做MPI_Send()
和MPI_Recv()
直到通信完成这些函数不返回(即,他们阻止)。 有所简化,这意味着传送到缓冲器MPI_Send()
可以重复使用,或者是因为MPI保存它的地方,或者因为它已经由目的地接收到的。 类似地, MPI_Recv()
当接收缓冲器已填充有有效数据返回。
相反,非阻挡通信使用完成MPI_Isend()
和MPI_Irecv()
这些函数立即返回(即,它们不会阻塞),即使通信还没有完成。 你必须调用MPI_Wait()
或MPI_Test()
看通信是否已经完成。
阻塞通信时使用是足够了,因为它是有点更容易使用。 非阻塞通信用于在必要时,例如,你可以调用MPI_Isend()
做一些计算,然后做MPI_Wait()
这允许计算和通信重叠,这通常导致改善的性能。
需要注意的是集合通信(例如,所有-减少)仅在其阻断版本高达MPIv2。 IIRC,MPIv3引入非阻塞集体通信。
MPI的发送模式的快速浏览可以看到这里 。
这个职位,虽然是有点老了,但我主张接受的答案。 语句“这些函数不返回,直到通信结束”是有点误导,因为阻塞的通信,并不能保证任何握手的B / W的发送和接收操作。
首先需要知道, 送有沟通的四种模式 : 标准,缓冲,同步和准备和每一种可以阻断和非阻塞
不像在发送, 接收仅具有一个模式 ,并且可以阻塞或非阻塞的 。
在进一步讨论之前,还必须明确的是,我明确提到哪一个是MPI_SEND \的Recv缓冲 ,哪一个是系统缓存 (这是由MPI库拥有的每个处理器的本地缓存用于通信的行列中移动数据组)
阻止通信 :堵不意味着该消息被传递到接收器/目的地。 这仅仅意味着(发送或接收)缓冲区可以重复使用。 为了重复利用缓冲区,这是足以将信息复制到另一个存储区,即库可以复制缓存数据自己在库中存储的位置,然后说了如MPI_SEND可以返回。
MPI标准非常清楚地去耦发送消息缓冲和接收操作。 一个阻塞发送可一旦消息被缓冲完成,即使没有匹配接收已发布。 但在某些情况下,消息缓冲可以从发送缓冲区昂贵的,因此直接复制到接收缓冲区可能是有效的。 因此MPI标准提供了四种不同的发送模式给用户一定的自由选择合适的发送模式了她的申请。 让我们来看看在每个通信模式发生了什么:
1.标准模式
在标准模式中,它是由所述MPI库,不论是否缓冲传出消息。 在图书馆决定缓冲传出消息的情况下,可以发送接收完成已调用的匹配,甚至之前。 在图书馆决定不缓存(由于性能原因,或由于缓冲区空间不可用)的情况下,发送之前,不会返回匹配的接收已经公布,在发送缓冲区中的数据已被转移到接收缓冲器。
因此MPI_SEND在标准模式是 ,在标准模式下发送可以开始不论是否匹配接收已经公布,其成功的完成可能取决于匹配的发生接收(由于它是实现意义的非本地依赖如果消息将被缓冲或没有)。
标准发送的语法如下:
int MPI_Send(const void *buf, int count, MPI_Datatype datatype,
int dest, int tag, MPI_Comm comm)
2.缓冲模式
就像在标准模式下,在缓冲模式发送,可以启动无关的事实匹配接收已发布和匹配接收已发布之前发送就可以完成。 然而,主要的区别在于出去的事实,如果发送的盯着,没有匹配接收张贴在传出消息必须进行缓冲。 注意如果匹配的接收被张贴的缓冲后发送能够愉快交会与开始收到的处理器,但万一没有收到,在缓冲模式下发送具有缓冲传出消息,允许发送完成。 在其整体缓冲发送是本地的 。 在这种情况下缓冲分配用户定义并在缓冲器空间不足的情况下,会发生错误。
语法发送缓冲区:
int MPI_Bsend(const void *buf, int count, MPI_Datatype datatype,
int dest, int tag, MPI_Comm comm)
3.同步模式
在同步发送模式,发送就可以开始不论是否匹配接收被张贴。 然而,发送将成功完成只有一个匹配的接收被张贴和接收器已经开始接收同步发送发送的消息。 同步发送的建成,不仅表明,在发送缓冲区可以重复使用,而且还接收进程已经开始接收数据的事实。 如果同时发送和接收被阻断则通信没有完成在任一通信处理器会合之前结束。
语法同步发送:
int MPI_Ssend(const void *buf, int count, MPI_Datatype datatype, int dest,
int tag, MPI_Comm comm)
4.就绪模式
与前三个模式,在就绪模式的发送可以只有匹配的接收已经发布启动。 发送的完成并不表明匹配任何接收并只告诉用户发送缓冲区可以重复使用。 使用准备模式A发送具有相同的语义标准模式或用约一个匹配的接收的附加信息的同步模式。 与通信的准备模式下正确地程序可以与同步发送或从性能差异对结果没有任何影响开的标准发送来代替。
语法准备发送:
int MPI_Rsend(const void *buf, int count, MPI_Datatype datatype, int dest,
int tag, MPI_Comm comm)
通过所有的4联锁发送在经历,他们似乎在主不同,但根据一个实现方式中的语义可能类似于另一个。
例如MPI_SEND一般是阻塞模式,但依赖于实现,如果信息的尺寸不是太大,MPI_SEND会传出消息,从发送缓冲区系统缓冲区(“这主要是现代企业制度的情况下),复制并立即返回。 让我们看看下面的例子:
//assume there are 4 processors numbered from 0 to 3
if(rank==0){
tag=2;
MPI_Send(&send_buff1, 1, MPI_DOUBLE, 1, tag, MPI_COMM_WORLD);
MPI_Send(&send_buff2, 1, MPI_DOUBLE, 2, tag, MPI_COMM_WORLD);
MPI_Recv(&recv_buff1, MPI_FLOAT, 3, 5, MPI_COMM_WORLD);
MPI_Recv(&recv_buff2, MPI_INT, 1, 10, MPI_COMM_WORLD);
}
else if(rank==1){
tag = 10;
//receive statement missing, nothing received from proc 0
MPI_Send(&send_buff3, 1, MPI_INT, 0, tag, MPI_COMM_WORLD);
MPI_Send(&send_buff3, 1, MPI_INT, 3, tag, MPI_COMM_WORLD);
}
else if(rank==2){
MPI_Recv(&recv_buff, 1, MPI_DOUBLE, 0, 2, MPI_COMM_WORLD);
//do something with receive buffer
}
else{ //if rank == 3
MPI_Send(send_buff, 1, MPI_FLOAT, 0, 5, MPI_COMM_WORLD);
MPI_Recv(recv_buff, 1, MPI_INT, 1, 10, MPI_COMM_WORLD);
}
让我们看看在每个等级在上面的例子中发生的事情
秩0试图发送到秩1和秩2,并从等级1和d 3接收。
排名第1,尝试发送排名0和3的排名,而不是从任何其他队伍得到了什么
等级2正试图从等级0接受,后来做的recv_buff接收到的数据的一些操作。
等级3试图发送排名0和1级接收
凡初学者感到困惑的是,等级0被发送到排名1,但1级还没有启动任何接收操作,因此通信应该阻止或失速,并在等级0第二发送声明不应该在所有被执行(这是什么MPI文档应力,它是实现中定义的传出消息是否将被缓冲或没有)。 在小尺寸的最现代化的系统,这样的消息(这里大小为1),很容易被缓冲,并MPI_SEND将返回并执行它的旁边MPI_SEND声明。 因此,在上述例子中,即使在1级接收未启动,在等级0 1 MPI_SEND将返回,它将执行其下一条语句。
在一个假设的情况下秩秩3 0之前开始执行,它会在第一个发送语句从发送缓冲区拷贝传出消息到系统缓存(在现代系统)),然后开始执行其接收语句。 一旦等级0完成它的两个发送语句和开始执行它的接收语句,通过秩3在系统中缓冲的数据在接收缓冲器中被复制在列0。
如果有在处理器开始接收操作并没有匹配发送张贴,进程将阻塞,直到接收缓冲区充满了它期待的数据。 在这种情况下的计算或其它MPI通信将被阻止/暂停除非MPI_RECV已经返回。
参透缓冲现象 ,应该返回,并多想想MPI_Ssend具有阻断通信的真实语义。 即使MPI_Ssend拷贝从发送缓冲器到系统缓存器中的传出消息(其再次被实现定义),必须注意MPI_Ssend不会返回,除非一些从接收处理已经由发送处理器接收确认(低电平格式)。
幸运的MPI决定让事情easer为用户接受的条款, 并且只有一个接收阻塞通信:MPI_RECV,并可以与任何上述四种发送模式的使用。 对于MPI_RECV, 阻断接收返回它包含在它的缓冲器中的数据后,才装置 。 这意味着,获得可以完成匹配发送已开始后才但并不意味着是否匹配发送完成之后才能完成。
二战期间这种阻塞调用发生的是,计算被停止,直到堵塞缓冲被释放。 这通常会导致计算资源作为发送/ RECV的浪费通常是从一个存储器位置到另一存储器位置复制数据,而在CPU寄存器保持空闲。
非阻塞通信 :对于非阻塞通信,该应用程序用于发送创建用于通信的请求和/或接收和回来的手柄,然后终止。 这就是所有需要保证执行过程。 即MPI库被通知操作已被执行。
对于发送侧,这允许与通信重叠计算。
用于接收器侧,这允许重叠通信开销的一部分,即,直接复制消息发送到接收侧的在应用程序的地址空间。
在使用阻挡通信,你必须关心发送和验证码领取例如看来电
if(rank==0)
{
MPI_Send(x to process 1)
MPI_Recv(y from process 1)
}
if(rank==1)
{
MPI_Send(y to process 0);
MPI_Recv(x from process 0);
}
在这种情况下会发生什么?
这很容易。
非阻挡装置计算和传输数据可以在同一时间发生为一个单一的过程。
同时阻止手段,嘿,伙计,你必须确保你已经完成了传输数据,然后回去完成下一个命令,这意味着如果有一个转移之后的计算,计算必须转移成功后。