3.4 通信模式 BACKWARDFORWARD


3.2.1节描述的发送调用是阻塞的: 它直到消息数据和信封已被安全取出和存储才返回以便发送者自由存取和重写发送缓存。消息可能被直接拷贝到匹配的接收缓存,或被拷贝到一个暂时的系统缓存。   

消息缓存退耦发送和接收操作。只要消息被缓存起来,既使接收者没有执行匹配接收,一个阻塞发送能完成。另一方面,消息缓存是昂贵的,因为它承担附加的存储器到存储器拷贝,而且它要求为缓存分配存储空间。MPI提供几个通信模式选择, 使你控制通信协议的选择。   

3.2.1节描述的发送调用使用标准的通信模式。在这种模式中,由MPI决定正在出发的消息是否被缓存。MPI可以缓存正出发的消息。这时,在引用一个匹配接收以前,发送调用可以完成。另一方面,缓存空间可以得不到,或因性能原因, MPI可以选择不缓存正出发的消息。这时,发送调用直到一个匹配接收登入并且数据被移入接收者才完成。   

所以,无论一个匹配接收是否登入,一个标准模式的发送能开始。它可以在匹配接收登入以前完成。标准模式的发送是非局部的:发送操作成功的完成依赖于一个匹配接收的发生。      

有三个附加的通信模式。   

无论一个匹配接收是否已登入,能够开始一个“缓存模式”的发送操作。它可以在一个匹配接收登入已前完成。但是,不象标准发送,这个操作是局部的,它的完成不依赖一个匹配接收的发生。因此,如果执行一个发送而没有匹配接收登入,那么MPI必须缓存正出发的消息, 以便允许发送调用完成。如果没有充足的缓存空间,一个错误将发生。可得到的缓存空间数量由用户控制--看3.6节。为使缓存模式有效可以要求用户分配缓存。   

无论一个匹配接收是否登入,能开始“同步模式”的一个发送操作。但是,只有一个匹配接收登入,接收操作已开始接收同步发送的消息时,发送操作将成功完成。所以,一个同步发送的完成不表示发送缓存能被再使用,但是表明接收者已到达执行的某一点,即它已开始执行匹配接收。如果发送和接收都是阻塞操作,那么同步模式的使用提供同步语义:两个进程在通信时聚会以前,一个通信不能完成。在这个模式下执行的一个发送是非局部的。   

只要匹配接收已登入,可以开始一个“准备好通信”模式的发送。否则,这个操作是错误的,其结果是无定义的。在某些系统,这允许移出一个信号交换式操作,并导致提高性能。发送操作的完成不依赖一个匹配接收的状态,只表明发送缓存能被再使用。准备好模式的一个发送操作,与一个标准发送操作或一个同步发送操作有相同的语义;只是发送者给系统提供附加的信息( 即:一个匹配接收已登入 ),能节省一些额外开销。因此,在一个正确的程序中,一个准备好发送能被一个标准发送替代,对程序的动作无影响而对性能有影响。   

为三个附加的通信模式提供三个附加的发送函数。由一个字母前缀表示通信模式:B 用于“缓存模式”,S 用于“同步模式”,R 用于“准备好模式”。

MPI_BSEND(buf, count, datatype, dest, tag, comm)
 IN buf 发送缓存的初始地址(选择型)
 IN count 发送缓存中元素的个数(整型)
 IN datatype 每个发送缓存元素的数据类型(句柄)
 IN dest 目标进程号(整型)
 IN tag 消息标志(整型)
 IN comm 通信子(句柄)

int MPI_Bsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) MPI_BSEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, IERROR)
 <type>BUF(*)
  INTEGER COUNT, DATATYPE, DEST, TAG, COMM, IERROR

以缓存模式发送。

MPI_SSEND(buf, count, datatype, dest, tag, comm)
 IN buf 发送缓存的初始地址(选择型)
 IN count 发送缓存中元素的个数(整型)
 IN datatype 每个发送缓存元素的数据类型(句柄)
 IN dest 目标进程号(整型)
 IN tag 消息标识(整型)
 IN comm 通信子(句柄)

int MPI_Ssend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)

MPI_SSEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, IERROR)
 <type> BUF(*)
 INTEGER COUNT, DATATYPE, DEST, TAG, COMM, IERROR)

以同步模式发送。

MPI_RSEND(buf, count, datatype, dest, tag, comm)
 IN buf 发送缓存的初始地址(选择型)
 IN count 发送缓存中元素的个数(整型)
 IN datatype 每个发送缓存元素的数据类型(句柄)
 IN dest 目标进程号(整型)
 IN tag 消息标识(整型)
 IN comm 通信子(句柄)

int MPI_Rsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)

MPI_RSEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, IERROR)
 <type>BUF(*)
 INTEGER COUNT, DATATYPE, DEST, TAG, COMM, IERROR   

以准备好模式发送。   

只有一个接收操作,能和任何发送操作模式匹配。在上节描述的接收操作是阻塞的:只有接收缓存包含新接收消息时, 它返回。在匹配的发送已完成以前,一个接收能完成( 当然, 只在匹配发送已开始后, 它能完成。)

在MPI的多线索实现中, 系统可以再调度一个阻塞发送或接收操作的线索, 并调度在同一地址执行的另一线索。这时,到通信完成时,用户才负责存取或修改一个通信缓存。否则,计算的结果是无定义的。   


Copyright: NPACT
BACKWARDFORWARD