⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpi375.htm

📁 该文件为mpich2的开发文档
💻 HTM
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
   <TITLE> ICPSEP Content
</TITLE>
   <META NAME="GENERATOR" CONTENT="Mozilla/3.0Gold (X11; I; SunOS 5.4 sun4m) [Netscape]">
</HEAD>
<BODY BGCOLOR="#F0F8FF">

<TABLE WIDTH="100%" >
<TR>
<TD align=left><FONT SIZE=+2>3.7.5 多路完成 </FONT></TD>

<TD align=right><A HREF="mpi374.htm" tppabs="http://arch.cs.pku.edu.cn/parallelprogramming/mpispec/mpi374.htm"><IMG SRC="backward.gif" tppabs="http://arch.cs.pku.edu.cn/image/backward.gif" ALT="BACKWARD" HEIGHT=32 WIDTH=32></A><A HREF="mpi38.htm" tppabs="http://arch.cs.pku.edu.cn/parallelprogramming/mpispec/mpi38.htm"><IMG SRC="forward.gif" tppabs="http://arch.cs.pku.edu.cn/image/forward.gif" ALT="FORWARD" HEIGHT=32 WIDTH=32></A>
</TD>
</TR>
</TABLE>

<P>
<HR WIDTH="100%"></P>

<P>能等待一个表中的任何、一些或全部操作的完成是方便的, 而不必等待一个特别消息。对MPI_WAITANY或MPI_TESTANY的一个调用能被用于等待几个操作之一的完成。对MPI_WAITALL或MPI_TESTALL的一个调用能被用于等待一个表中的所有挂起操作。对MPI_WAITSOME或MPI_TESTSOME的一个调用能被用于完成一个表中的所有操作。
</P>

<P>MPI_WAITANY(count, array_of_requests, index, status) <BR>
 IN count 表长(整型) <BR>
 INOUT array_of_requests 请求数组(句柄数组) <BR>
 OUT index 被完成操作的句柄索引(整型) <BR>
 OUT status 状态对象(状态类型) </P>

<P>int MPI_Waitany(int count, MPI_Request *array_of_requests, int *index,
<BR>
 MPI_Status *status) </P>

<P>MPI_WAITANY(COUNT, ARRAY_OF_REQUESTS, INDEX, STATUS, IERROR) <BR>
 INTEGER COUNT, ARRAY_OF_REQUESTS(*), INDEX, STATUS(MPI_STATUS_SIZE),  <BR>
 IERROR </P>

<P>阻止直到与数组联结的操作之一已被完成。如果多于一个操作能终结,那么这个是被任意选择的。在index中返回这个数组的那个请求的索引,
在status中返回正完成通信的状态。(C语言中, 数组下标从0开始, Fortran中下标从1开始)如果一个非阻塞通信操作已分配这个请求,那么解出分配并设置请求句柄为MPI_REQUEST_NULL。
  </P>

<P>这个array_of_requests表可以包含null或不活动句柄。如果这个表包含非活动句柄(表长0或所有输入是null或非活动),那么这个调用用index=MPI_UNDEFINED。MPI_WAITANY(count,
array_of_requests, index, status)的执行与MPI_WAIT(&amp;array_of_requests[i],status)的执行有相同的作用,
这个i是index的返回值。有包含活输入的一个数组的MPI_WAITANY等价于MPI_WAIT。
</P>

<P>MPI_TESTANY(count, array_of_requests, index, flag, status) <BR>
 IN count 表长(整型) <BR>
 INOUT array_of_requests 请求数组(句柄数组) <BR>
 OUT index 被完成操作的索引, 或MPI_UNDEFINED如果没有被 完成的(整型) <BR>
 OUT flag 真, 如果一个操作完成(逻辑型) <BR>
 OUT status 状态对象(状态类型)</P>

<P>int MPI_Testany(int count, MPI_Request *array_of_requests, int *index,
<BR>
       int *flag, MPI_Status *status)</P>

<P><BR>
MPI_TESTANY(COUNT, ARRAY_OF_REQUESTS, INDEX, FLAG, STATUS, IERROR) <BR>
 LOGICAL FLAG <BR>
 INTEGER COUNT, ARRAY_OF_REQUESTS(*), INDEX, STATUS(MPI_STATUS_SIZE),  <BR>
 IERROR </P>

<P>检测与激活句柄联结的一个或没有操作的完成。前一种情况,它返回flag = 真,
在index中返回这个数组中这个请求的下标, 并在status中返回那个操作的状态;
如果一个非阻塞通信调用分配这个请求, 那么解出这个请求并设句柄为MPI_REQUEST_NULL。(在C语言中,
数组下标从0开始, Fortran中从1开始)在后一种情况, 它返回flag = 假, 在index中返回一个值MPI_UNDEFINED和status为无定义。这个数组可以包含null或不活动句柄。如果数组不包含活动句柄,那么这个调用立刻返回,flag
= 假, index = MPI_UNDEFINED, 和status无定义。   </P>

<P>MPI_TESTANY(count, array_of_requests, index, status)的执行与MPI_TEST(&amp;array_of_requests[i],
flag, status) 的执行有同样的作用, 对i=0,1 ,..., count-1, 以任意顺序, 直到一个调用返回flag=
真, 或全部失败。在前一种情况,index设为i的最后值, 在后一种情况, 它被设为MPI_UNDEFINED。有包含活动输入的一个数组的MPI_TESTANY是等价于MPI_TEST。
   </P>

<P>MPI_WAITALL( count, array_of_requests, array_of_statuses) <BR>
 IN count 表长(整型) <BR>
 INOUT array_of_requests 请求数组(句柄数组) <BR>
 OUT array_of_statuses 状态对象的数组(状态数组) </P>

<P>int MPI_Waitall(int count, MPI_Request *array_of_requests, <BR>
       MPI_Status *array_of_statuses) </P>

<P>MPI_WAITALL(COUNT, ARRAY_OF_REQUESTS, ARRAY_OF_STATUSES, IERROR) <BR>
 INTEGER COUNT, ARRAY_OF_REQUESTS(*) <BR>
 INTEGER ARRAY_OF_STATUSES(MPI_STATUS_SIZE,*), IERROR </P>

<P>阻止到与表中的活动句柄联结的所有通信操作完成为止, 返回所有这些操作的状态(这包括表中没有活句柄的情况)。两个数组有相同的有效输入数。在数组array_of_statuses中的第i个输入设为第i个操作的返回状态。由非阻塞通信操作创建的请求被解出分配,数组中相应的句柄设为MPI_REQUEST_NULL。这个表可以包含null或非活动句柄。这个调用在每个这样输入状态中返回tag
= MPI_ANY_TAG,source =MPI_ANY_SOURCE,并且每个状态输入也被构成,以便调用MPI_GET_COUNT和MPI_GET_ELEMENTS,
返回count = 0。   </P>

<P>对于i = 0, ..., count-1,以任意顺序执行MPI_WAITALL(count,array_of_requests,array_of_statuses),
与MPI_WAIT(&amp;array_of_request[i],&amp;array_of_statuses[i])的执行有相同的作用。有一个长度的数组的MPI_WAITALL等价于MPI_WAIT。
</P>

<P>MPI_TESTALL(count, array_of_requests, flag, array_of_statuses) <BR>
 IN count 表长(整型) <BR>
 INOUT array_of_requests 请求数组(句柄数组) <BR>
 OUT flag (逻辑型) <BR>
 OUT array_of_statuses 状态对象数组(状态数组) </P>

<P>int MPI_Testall(int count, MPI_Request *array_of_requests, int *flag,
<BR>
    MPI_Status *array_of_statuses) </P>

<P>MPI_TESTALL(COUNT, ARRAY_OF_REQUESTS, FLAG, ARRAY_OF_STATUSES, IERROR)
<BR>
 LOGICAL FLAG <BR>
 INTEGER COUNT, ARRAY_OF_REQUESTS(*), <BR>
 ARRAY_OF_STATUSES(MPI_STATUS_SIZE,*), IERROR </P>

<P>如果与在数组中活动句柄联结的所有通信都已完成, 返回flag = 真(这包括表中没有活动句柄的情况)。这时,每个相应于一个活动句柄请求的状态输入设为相应通信的状态;如果由一个非阻塞通信调用已分配一个请求,那么解出分配,并设句柄为MPI_REQUEST_NULL。相应于null和非活动句柄的每个状态输入设为返回tag
= MPI_ANY_TAG, source = MPI_ANY_SOURCE, 并被安装以便对MPI_GET_COUNT和MPI_GET_ELEMENTS的调用返回count
= 0。 </P>

<P>否则,返回flag = false(假), 不修改请求, 状态输入的值无定义。这是一个局部操作。</P>

<P>MPI_WAITSOME(incount,array_of_requests,outcount,array_of_indices, array_of_statuses)
<BR>
 IN incount 请求数组的长度(整型) <BR>
 INOUT array_of_requests 请求数组(句柄数组) <BR>
 OUT outcount 已完成请求的数目(整型) <BR>
 OUT array_of_indices 已完成操作的下标数组(整型数组) <BR>
 OUT array_of_statuses 已完成操作的状态数组(状态数组) </P>

<P>int MPI_Waitsome(intincount,MPI_Request *array_of_request, int *outcount,<BR>
       int *array_of_indices, MPI_Status *array_of_statuses) </P>

<P>MPI_WAITSOME(INCOUNT, ARRAY_OF_REQUESTS, OUTCOUNT, ARRAY_OF_INDICES,
<BR>
       ARRAY_OF_STATUSES, IERROR) <BR>
 INTEGER INCOUNT, ARRAY_OF_REQUESTS(*), OUTCOUNT, ARRAY_OF_INDICES(*), 
<BR>
 ARRAY_OF_STATUSES(MPI_STATUS_SIZE,*), IERROR </P>

<P>等待直到表中与活句柄联结的至少一个操作已完成。在outcount中返回来自已完成的表array_of-requests的请求数目。在数组array_of_indices的第一个outcount位置返回这些操作的下标(在数组array_of_requests中的下标;
C中从0开始下标, Fortran中从1开始下标)。在数组array_of_status的第一个outcount位置返回这些已完成操作的状态。如果已完成的一个请求已被一个非阻塞通信调用分配,那么它被解出分配并设所联结的句柄为MPI_REQUEST_NULL。
  </P>

<P>如果表中不包含活动句柄, 那么这个调用立刻以outcount = 0 返回。</P>

<P>MPI_TESTSOME(incount,array_of_requests,outcount,array_of_indices,array_of_statuses)
<BR>
 IN incount 请求数组的长度(整型) <BR>
 INOUT array_of_requests 请求数组(句柄数组) <BR>
 OUT outcount 已完成请求的数目(整数) <BR>
 OUT array_of_indices 已完成操作的下标数组(整型数组) <BR>
 OUT array_of_statuses 已完成操作的状态对象数组(状态数组) </P>

<P>int MPI_Testsome(int incount, MPI_Request *array_of_requests, int *outcount,
<BR>
       int*array_of_indices, MPI_Status *array_of_statuses) <BR>
MPI_TESTSOME(INCOUNT, ARRAY_OF_REQUESTS, OUTCOUNT, ARRAY_OF_INDICES,<BR>
       ARRAY_OF_STATUSES, IERROR) <BR>
 INTEGER INCOUNT, ARRAY_OF_REQUESTS(*), OUTCOUNT,ARRAY_OF_INDICES(*),  <BR>
 ARRAY_OF_STATUSES(MPI_STATUS_SIZE,*), IERROR </P>

<P>除了它立刻返回,行为象MPI_WAITSOME。如果没有操作被完成,它返回outcount
= 0。   </P>

<P>MPI_TESTSOME是一个局部操作, 它立刻返回, 而如果传送给它至少包含一个活句柄的一个表时,MPI_WAITSOME将阻塞直到一个通信完成为止。两个调用完成一个合理的请求:如果在一个请求表中重复出现的一个接收请求传送给MPI_WAITSOME或MPI_TESTSOME,
并且一个匹配操作已被登入, 那么接收将最终成功, 除非发送被另一个接收满足;
发送操作类似。   </P>

<UL>
<P><I>给用户的建议</I>. MPI_TESTSOME的使用比MPI_TESTANY的使用更有效。前者返回所有关于已完成通信的消息,后者,为完成每个通信要求一个新的调用。
     </P>

<P>有多路客户的一个服务能使用MPI_WAITSOME, 以免不服务任何客户。客户用服务请求给服务器发送消息。拥有一个接收请求的服务器为每个客户调用MPI_WAITSOME,
处理所用已完成的请求。如果用MPI_WAITANY调用替代, 那么当一个客户的请求总先存在时,
另一个客户不能被服务。(<I>给用户的建议结束</I>)。   </P>

<P><I>给实现者的建议</I>. MPI_TESTSOME尽可能与许多挂起通信一样将完成。(<I>给实现者的建议结束</I>)。
</P>
</UL>

<P>例子3.14 客户-服务代码(不服务能发生)。 </P>

<P>CALL MPI_COMM_SIZE(comm, size, ierr) <BR>
CALL MPI_COMM_RANK(comm, rank, ierr) <BR>
IF(rank &gt; 0) THEN ! 客户代码 <BR>
 DO WHILE(.TRUE.) <BR>
  CALL MPI_ISEND(a, n, MPI_REAL, 0, tag, comm, request, ierr) <BR>
  CALL MPI_WAIT(request, status, ierr) <BR>
 END DO <BR>
ELSE ! rank=0 -- 服务器代码 <BR>
 DO i=1, size-1 <BR>
  CALL MPI_IRECV(a(1,i), n, MPI_REAL, 0, tag, <BR>
       comm, request_list(i), ierr) <BR>
 END DO <BR>
 DO WHILE(.TRUE.) <BR>
  CALL MPI_WAITANY(size-1, request_list, index, status, ierr) <BR>
  CALL DO_SERVICE(a(1,index)) !handle one message <BR>
  CALL MPI_IRECV(a(1, index), n, MPI_REAL, 0, tag, <BR>
       comm, request_list(index), ierr) <BR>
 END DO <BR>
END IF </P>

<P>例子3.15 使用MPI_WAITSOME的同样的代码。 <BR>
CALL MPI_COMM_SIZE(comm, size, ierr) <BR>
CALL MPI_COMM_RANK(comm, rank, ierr) <BR>
IF(rank &gt; 0) THEN ! 客户代码 <BR>
 DO WHILE(.TRUE.) <BR>
  CALL MPI_ISEND(a, n, MPI_REAL, 0, tag, comm, request, ierr) <BR>
  CALL MPI_WAIT(request, status, ierr) <BR>
 END DO <BR>
ELSE ! rank=0 -- 服务器代码 <BR>
 DO i=1, size-1 <BR>
  CALL MPI_IRECV(a(1,i), n, MPI_REAL, 0, tag, <BR>
       comm, request_list(i), ierr) <BR>
 END DO <BR>
 DO WHILE(.TRUE.) <BR>
  CALL MPI_WAITSOME(size, request_list, numdone, <BR>
           index_list, status_list, ierr) <BR>
  DO i=1, numdone <BR>
   CALL DO_SERVICE(a(1, index_list(i))) <BR>
   CALL MPI_IRECV(a(1, index_list(i)), n, MPI_REAL, 0, tag, comm, request_list(i),
ierr) <BR>
  END DO <BR>
 END DO <BR>
END IF 
<HR WIDTH="100%"></P>

<TABLE WIDTH="100%" >
<TR>
<TD align=left>Copyright: NPACT <BR>
</TD>

<TD align=right><A HREF="mpi374.htm" tppabs="http://arch.cs.pku.edu.cn/parallelprogramming/mpispec/mpi374.htm"><IMG SRC="backward.gif" tppabs="http://arch.cs.pku.edu.cn/image/backward.gif" ALT="BACKWARD" HEIGHT=32 WIDTH=32></A><A HREF="mpi38.htm" tppabs="http://arch.cs.pku.edu.cn/parallelprogramming/mpispec/mpi38.htm"><IMG SRC="forward.gif" tppabs="http://arch.cs.pku.edu.cn/image/forward.gif" ALT="FORWARD" HEIGHT=32 WIDTH=32></A>
</TD>
</TR>
</TABLE>

</BODY>
</HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -