5.4 通信子管理 BACKWARD FORWARD


本节描述MPI中的通信子维护。对通信子的访问是本地的,它们的执行不要求进程间通信。创建通信子的操作是集合性的可能要求进程间通信.

对实现者的建议: 高质量的实现应该通过为一个集合通信分配多个上下文的方法来减小(对同一组或其子集)通过多次调用创建通信子所引起的开销。.

5.4.1 通信子访问子

下面的都是本地操作.

MPI_COMM_SIZE(comm,size)

输出: size comm组内的进程数(整数)

int MPI_Comm_size(MPI_Comm comm, int *size)

MPI_COMM_SIZE(COMM,SIZE,IERROR)

基本原理: 本函数等价于用MPI_COMM_GROUP访问通信子的组(见下面),使用MPI_GROUP_SIZE计算大小,通过MPI_GROUP_FREE释放临时组. 由于本函数使用很广泛故而介绍了这一捷径.(基本原理结束)

对用户的建议: 本函数指出了包含在一个通信子中的进程数.对于MPI_COMM_WORLD,它指出了可得到的全部进程数(对于此MPI版本,一旦初始化发生, 没有标准的方法来改变进程数)

此调用通常与下一个调用一起使用以决定给定的库或程序所能同时发生的数目.下一个调用MPI_COMM_RANK指出了在0..size-1范围内调用的每个进程的序列号, 在这里size是 MPI_COMM_SIZE的返回值. (对用户的建议结束)

MPI_COMM_RANK(comm,rank)

int MPI_Comm_rank(MPI_Comm comm, int *rank)

MPI_COMM_RANK(COMM,RANK,IERROR)

基本原理: 本函数等价于用MPI_COMM_GROUP访问通信子的组(见下面),用 MPI_GROUP_RANK计算大小,然后通过MPI_GROUP_FREE释放临时组. 由于本函数使用很广泛故而介绍了这一捷径.(基本原理结束)

对用户的建议: 本函数给出了特定通信子组内的进程序列号.如前所述,当将其与MPI_COMM_SIZE结合起来是很有用的.许多程序是按照主-从模型书写的,在这些程序里, 总有一个进程(例如序列号为0的进程)作为超级用户,而其它的进程作为计算结点.在这一框架 下,前面的两个调用对于决定一个通信子内不同进程的地位是很有用的.(对用户的建议结束)

MPI_COMM_COMPARE(comm1,comm2,result)

int MPI_Comm_compare(MPI_Comm comm1,MPI_Comm comm2,int *result)

MPI_COMM_COMPARE(COMM1,COMM2,RESULT,IERROR)

当且仅当comm1和comm2是同一对象(同一组且相同的上下文)的句柄时,结果为 MPI_IDENT. 如果各组的组成元素和序列号次序都是相同的, 则结果为MPI_CONGRUENT; 这些通信子仅通过上下文相互区分. 如果两个通信子的组成员相同但序列号次序不同.则结果是 MPI_SIMILAR.否则结果是MPI_UNEQUAL.

5.4.2 通信子构造子

下面是可被与comm相关的组内所有进程调用的集合函数.

基本原理: 因为通信子需要创建新的通信子, 所以我们注意到MPI中有一个"鸡生蛋, 蛋生鸡"的部分. 所有MPI通信子的基础通信子,即MPI_COMM_WORLD,是在MPI的外部被定义的. 这一模型是经过周到的讨论后被确定下来的,选择此模型的目的是为了提高用MPI写程序的安全性.(基本原理结束)

MPI_COMM_DUP(comm,newcomm)

int MPI_Comm_dup(MPI_Comm comm,MPI_Comm *newcomm)

MPI_COMM_DUP(COMM,NEWCOMM,IERROR)

MPI_COMM_DUP用相联关键字值复制已存在的通信子comm. 对于每一个关键字值,各自拷贝的回调函数确定在新通信子中与此关键字相联的属性值; 拷贝回调可能进行的一个特殊动作是从新通信子中删除属性. 在newcomm中除一个新的上下文外,要返回一个具有同样组的新通信子,及任何复制的缓冲信息(见5.7.1节)

对用户的建议: 本操作用一个复制的通信空间来提供一个并行库调用,此通信空间与原来通信子具有相同的属性值. 包括任意属性(见下面)和拓扑(见第六章). 即使存在涉及通信子comm的挂起的点对点通信,此调用也是有效的.一个典型的调用可能在并行调用开始时涉及一个MPI_COMM_DUMP, 并在调用结束时涉及一个针对复制通信子的MPI_COMM_FREE. 其它的通信子管理模型也是可能的. 此调用可应用于组内和组间通信子.(对用户的建议结束)

对实现者的建议: .我们无须实际复制组信息, 而只是加一个新的引用并对引用计数增值. 基于写的复制可用于缓冲信息.(对实现者的建议结束)

MPI_COMM_CREATE(comm,group,newcomm)

int MPI_Comm_create(MPI_Comm,MPI_Group group,MPI_Comm *newcomm)

MPI_COMM_CREATE(COMM,GROUP,NEWCOMM,IERROR)

此函数用由group所定义的通信组及一个新的上下文创建了一个新的通信子newcomm. comm中的缓冲信息不传播给newcomm. 对于不在group中的进程,本函数返回MPI_COMM_NULL. 如果所有的group参数不都具有同样的值, 或者如果group不是与comm相联的组的子集, 则调用将出错, 注意comm中的所有进程都将执行这一调用,即使他们不属于这一新组. 本调用仅适用于组内通信子。

基本原理: 整个comm组参加调用的要求出于以下考虑:

(基本原理结束)

对用户的建议: MPI_COMM_CREATE为分离MIMD计算, 用分离通信空间的方法, 提供了构造进程子集的方式.从MPI_COMM_CREATE获得的newcomm可被用于对MPI_COMM_CREATE(或其它通信子构造器)的后续调用,以进一步将计算细分为并行子计算。更一般的服务是由MPI_COMM_SPLIT提供的(见下面). (对用户的建议结束)

对实现者的建议: 因为所有进程调用MPI_COMM_DUP和MPI_COMM_CREATE时都提供相同的group参数, 理论上在组的范围内实现一个没有通信的唯一上下文是可能的. 但是, 这些函数的本地执行需要使用一个更大的名字空间并减少错误检查. 因此实现时可能在这些相互冲突的目标之间进行折衷, 例如在一个集合操作里进行多上下文的大量分配.

重要性: 如果所创建的通信子不涉及进程间同步, 则通信系统应该能处理在某一个上下文内到达的消息, 该上下文尚未在接收进程中分配.(对实现者的建议结束)

MPI_COMM_SPLIT(comm,color,key,newcomm)

int MPI_Comm_split(MPI_Comm comm,int color, int key,MPI_Comm *newcomm)

MPI_COMM_SPLIT(COMM,COLOR,KEY,NEWCOMM,IERROR)

INTEGER COMM,COLOR,KEY,NEWCOMM,IERROR

本函数将与comm相关的组划分为若干不相连的子组,每一个子组对应color一个值. 每一个子组包含具有同样color的所有进程. 在每一个子组内, 进程按照参数key所定义的值的次序进行排列, 并根据它们在旧组中的序列号携带打破后的联系. 为每个子组创建一个新的通信子并在newcomm中返回.一个进程可能提供color值MPI_UNDEFINED, 在这种情况下,newcomm返回MPI_COMM_NULL. 这是一个集合调用, 但是允许每个进程为color和key提供不同的值.

对MPI_COMM_CREATE(comm,group,newcomm)的调用等价于对MPI_COMM_SPLIT(comm,color,key,newcomm)的调用, 在这里, group的所有成员在group中提供color=0以及key=序列号,不是group成员的所有进程提供color=MPI_UNDEFINED. 函数MPI_COMM_SPLIT允许对一组进行更一般的划分, 此划分用可选的重排序将一组分为一个或更多的子组。此调用仅适用于组内通信子.

对用户的建议:这是一个能将单通信进程组划分成k个子组的功能很强大的机制, 其中k由用户隐含选定(由所有进程上所声明的colors的数目所选定)。每一个结果通信子都是非重迭的。这样一个划分对于定义一个诸如多网格或线性代数等计算的层次是很有用的。

对MPI_COMM_SPLIT的多重调用可用于克服下面的要求:任意调用都没有结果通信子重迭(每个进程仅是每个调用的一个color). 按这种方式, 可创建多重重迭通信结构. 鼓励以这种分离的操作来创造性的使用color和key.

注意:对于一个严格的color, 关键字的值不需要是惟一的. MPI_COMM_SPLIT可负责根据这个关键字按降序对进程进行分类,并以一个一致的方式打破它们之间的联系。如果以同样的方式指定所有的关键字,则给定color内的所有进程将象它们在父组中一样具有相关的序列号顺序. (一般来说,它们具有不同的序列号)。

实质上,将给定color内的所有进程中的关键字的值置为0意味着用户真正不关心新通信子中的进程的序列号次序. (对用户的建议结束)

5.4.3 通信子析构子

MPI_COMM_FREE(comm)

int MPI_Comm_free(MPI_Comm *comm)

MPI_COMM_FREE(COMM,IERROR)

这是一个标志通信对象撤消的集合操作。该句柄被置为MPI_COMM_NULL。任何使用此通信子的挂起操作都会正常完成;仅当没有对此对象的活动引用时,它才会被实际撤消。该调用适合于组内和组间通信子。可以任意次序调用所有属性信息的删除回调函数。

对实现者的建议:可使用一个引用计数机制:每次调用MPI_COMM_DUP则计数值增加,而每次调用MPI_COMM_FREE则计数值减少。此对象在计数达到0时被最终撤消。 虽然是集合公共操作且MPI库的调试版本可能会选择同步,预计此操作仍会正常实现本地化。(对实现者的建议结束)


Copyright: NPACT BACKWARD FORWARD