3.9 坚持式通信请求 BACKWARDFORWARD


经常会有这样的情况,一个通信在一个并行计算的内部循环中不断地以同样的参数被执行。在这种情况下,该通信可以优化:把这些通信参数一次性捆绑到一个坚持式通信请求,然后不断用该请求初始化和完成消息。这样创建的坚持式请求可以被看作一个通信端口或者一个"半通道"(harf_channel)。它不能提供一个传统通道的完整功能,因为没有捆绑发送端口和接收端口。这种构造可以降低在进程和通信控制器之间的通信过载,但不能降低两个通信控制器之间的过载。接收一个坚持式发送请求发出的消息不一定必须用坚持式接收请求,反之亦然。

以下的四个调用创建坚持式通信请求。这些调用不涉及通信。

MPI_SEND_INIT(buf,count,datatype,dest,tag,comm,request) 
int MPI_Send_init(void* buf, int count, MPI_Datatype,int dest, int tag, MPI_Comm comm, MPI_Request *request) 
MPI_SEND_INIT(BUF,COUNT,DATATYPE,DEST,TAG,COMM,REQUEST,IERRR) BUF (*) 
INTEGER REQUEST,COUNT,DATATYPE,DEST,TAG,COMM,REQUEST,IERRROR 

创建一个坚持式标准模式发送操作的通信请求,并和一个发送操作的所有参数捆绑到一起。

MPI_BSEND_INIT(buf,count,datatype,dest,tag,comm,request) 
int MPI-Bsend_init(void* buf,int count,MPI_Datatype datatype,int dest, int tag, MPI_Comm comm,MPI_Request *request) 
MPI_BSEND_INIT(BUF,COUNT,DATATYPE,DEST,TAG,COMM,REQUEST,IERROR) BUF (*) 

创建一个缓冲模式发送的坚持式通信请求。

MPI_SSEND_INIT(buf,count,datatype,dest,tag,comm,request) 
int MPI-Ssend_init(void* buf,int count,MPI_Datatype datatype,int dest, int tag, MPI_Comm comm,MPI_Request *request) 
MPI_SSEND_INIT(BUF,COUNT,DATATYPE,DEST,TAG,COMM,REQUEST,IERROR).BUF (*) 
创建一个同步模式发送操作的坚持式通信目标。 
MPI_RSEND_INIT(buf,count,datatype,dest,tag,comm,request) 
int MPI-Rsend_init(void* buf,int count,MPI_Datatype datatype,int dest, int tag, MPI_Comm comm,MPI_Request *request) 
MPI_RSEND_INIT(BUF,COUNT,DATATYPE,DEST,TAG,COMM,REQUEST,IERROR) BUF (*) 
创建一个就绪模式发送操作的坚持式通信目标。 
MPI_RECV_INIT(buf,count,datatype,dest,tag,comm,request) 
int MPI-Rsend_init(void* buf,int count,MPI_Datatype datatype,int source, int tag, MPI_Comm comm,MPI_Request *request) 
MPI_RECV_INIT(BUF,COUNT,DATATYPE,SOURCE,TAG,COMM,REQUEST,IERROR) BUF (*) 
INTEGER COUNT,DATATYPE,SOURCE,TAG,COMM,REQUEST,IERROR 

为接收操作创建一个坚持式通信请求.参数buf标为OUT是因为用户通过传递该参数给MPI_RECV_INIT给予接收缓冲区写权限.

一个坚持式通信请求在创建后处于非活动状态,没有活动的通信附在该请求中.

一个使用坚持式请求的通信(发送或接收)使用MPI_START初始化.

MPI_START(request) 
int MPI_Start(MPI_Request *request) 
MPI_START(REQUEST,IERROR) 

request参数是一个由前面介绍的五个调用中的任一个返回的句柄.相关的请求应该是非激活状态.一旦使用该调用,请求成为激活状态.

如果这是一个就绪模式发送请求,则在该调用之前应该先公布一个匹配接收.通信缓冲区在该调用后应该被禁止访问,直到操作完成.

该调用是本地调用,和3.7中介绍的非阻塞通信操作的情况相似.即一个用MPI_SEND_INIT创建的请求来调用MPI_START产生的通信和用MPI_ISEND调用产生的通信效果一样;一个用MPI_BSEND_INIT创建的请求来调用MPI_START产生的通信和MPI_IBSEND调用产生的通信效果相同;等等.

MPI_STARTALL(count,array_of_requests) 
int MPI_Startall(int count, MPI_Request *array_of_requests) 
MPI_STARTALL(COUNT, ARRAY_OF_REQUESTS,IERROR) 

开始与array_of_request中所有请求相关联的通信.一个MPI_STARTALL调用等价于调用MPI_START(&array_of_request[i])以增序执行i=0,...,count-1.

一个由MPI_START或MPI_STARTALL调用开始的通信由MPI_WAIT,MPI_TEST或在3.7.5中介绍的调用来完成.这些调用的成功完成将使请求处于非激活状态.该请求并未被释放,它可以被MPI_START或MPI_STARTALL重新激活.

一个坚持式请求可以用MPI_REQUEST_FREE来释放(3.7.3)

MPI_REQUEST_FREE可以在坚持式请求被创建以后的任何地方被调用.可是,只有当一个请求成为非活动状态时才可以被取消.活动的接收请求是不应被释放的.否则它将不可能检测接收是否完成.一般情况下最好是在请求处于非活动状态下的时候在释放他们.如果遵循这一规则,则本节描述的调用将以以下顺序调用:

创建 ( 开始 完成 )* 释放,

这里*指零次或多次重复.如果同一个通信目标被多个线索同时使用, 则用户需要自己来协调这些调用是他们遵循正确的顺序.

一个用MPI_START初始化的发送操作可以被任何接收操作匹配,类似地,一个用MPI_START初始化的接收操作可以接收任何发送操作产生的消息.


Copyright: NPACT BACKWARDFORWARD