程序规范
在标准中对于参数的说明有三种类型,如下:
IN 仅使用但不更新
OUT 仅更新但不使用
INOUT 皆有
这个说明仅仅是只是告诉你参数会被如何使用,但是并不会强制落实到具体的实现上。
在这先提一嘴,MPI中有一类不透明类型,被称之为opaque type
。指的是无法被用户直接访问,只能通过句柄访问,其大小和形状对用户不可见的类型,如groups
datatypes
communicators
等。如果一个不透明类型被作为参数,那么他的参数说明为OUT或INOUT,哪怕其句柄并未被更新。
如果一个参数在一个进程中为IN,但是在另一个线程中为OUT,那么他的类型说明为INOUT。
如果参数说明为OUT或INOUT,那么这个参数不能有其他别名(或者说其他指针?),如标准指出以下程序是不被允许的。
|
|
术语
在标准中,message data bufferr
为进程中接受者或收发者的缓冲区,file data buffer
为MPI的I/O程序建立的缓冲区,data buffer
的语义为两者之一,具体情况具体分析。
MPI操作(MPI Operation)
一个MPI操作是由MPI库函数所构成的一系列数据传输或同步操作,由四个步骤组成。
- 初始化(Initialization)接受参数表但不会动缓冲区里数据。
- 启动(starting)接受缓冲区的控制权。注意,一般初始操作(initiation)包括了前两个步骤。
- 完成(Completion)返回缓冲区的控制权并告知参数已经更新完成。注意,一个MPI操作只有在实行了这个阶段才能算完成(complete)。
- 释放(Freeing)返回剩下参数表的控制权。
MPI操作分为形式,分别为阻塞(Blocking),非阻塞(Nonblocking)和持久(Persistent),区别如下:
阻塞操作:四个阶段全在一个过程调用(Procedure call)里。
非阻塞操作:前两个阶段在一个非阻塞过程调用里,而后两个阶段在另一个阻塞或非阻塞的过程调用里。
持久操作:每个阶段都在一个单独的过程里,过程为阻塞或非阻塞。 划开一个发送操作,在开始阶段结束时会有一个额外的调用来启动每一部分的接收者缓存。 划开一个接收操作,在操作结束前会允许用户访问接受缓存来确认数据是否正确接受。(这一部分有些怪,但是标准文档就是这么写的)
开始阶段也被称为激活阶段(active),初始化和完全阶段也被称为失活阶段(inactive,我不知道如何翻译,姑且就这么叫好了)。
激活通信和I/O操作也被称之为挂起(pending)操作,注意到一个挂起操作可以是一个开始但还没完成的持久或非阻塞操作,抑或是一个还未完成的阻塞操作(比如一个正在等待信息的接受操作)
从另一个角度,操作也可以分为群体通信或非群体通信
群体操作:一个群中的一个进程或一群进程而言,操作会也可能不会在群的所有进程开始前完成(挺拗口)。可能是阻塞、非阻塞或持久操作。
非群体操作:上述的补集。
有时一个操作在需要其他相关操作启动了才可以完成,比如一个接收操作需要发送操作启动了才能完成。这个现象被称之为使能(enabled)。但是有些mpi的实现会把使能优化,让一个操作在使能前就完成了。
有些操作是先验使能(pirori enabled)的,比如一个缓存发送操作不需要接受操作启动即可完成。
一旦一个操作是使能的,那么这个操作必须完成。一个操作可能在启动阶段前就已经是使能的了。比如接收操作。
使能的要求是不对称的,一个操作可能需要他所有相关的操作都完成了启动,但是自己却不一定需要启动。
MPI过程(MPI Procedure)
过程也可以分为两种,如下所示:
非本地(Nonlocal):过程需要其他相关的过程在另一个进程中被调用才能返回,那么称之为非本地的。
本地(Local):上述补集