8.1 活动处理器集合  BACKWARDFORWARD


活动处理器是HPF2.0中所使用的处理器和处理器排列观点的扩展。在那里,语言假定存在一个(静态)处理器集合,并且程序使用这些处理器来存储数据(例如通过DISTRIBUTE指令)和执行计算(例如通过FORALL语句的执行)。虽然对处理器集合的更好划分非常有用(例如,7.7节中向处理器子集的映射或者当解释基于子数组计算的性能时),但却很少被提及。然而,诸如任务并行这些特征需要考虑一个更加动态的处理器集合。特别是回答关于“哪个处理器当前正在执行”这样的问题对于定义这些特征非常有用。

简单地讲,一个活动处理器是执行一条HPF语句(或语句组)的处理器。除数据初始化访问和结果回写之外,活动处理器执行语句所需的所有操作。一些操作要求某些特定处理器是活动的(如下所示),但是对于大多数部分在执行任何语句时,任何处理器都可以是活动的。一个HPF程序开始执行时,所有处理器都是活动的。如8.2节所描述的,ON指令在其作用域期间对活动处理器集合进行了限制。考虑这个简单例子(此例具有显而易见直观的意义):

 !HPF$ ON HOME(Z(2))
 X(1)=X(1)+Y(2)*Z(3)

令X,Y,Z具有相同的分配方式。依据ON指令,语句应按如下方式执行:

  1. 拥有Z(2)的处理器被标志为活动处理器。这一步在编译时就可能完成,而其它的则必须等到执行时。
  2. 活动处理器可获得X(1),Y(2),Z(3)的值。由于具有同一分配方式,所以Y(2)已被存储在那里。根据数据分配方式和运行程序的硬件,其它值重获得可能对应于活动处理器从存储器中装载到寄存器中,否则也可能意味着两个其它的处理器将信息发送给活动处理器。
  3. 活动处理器使用最后一步所发送的值来执行一个加法和一个乘法。前面的数据移动允许这些操作在本地被执行。
  4. 结果被存储在X(1)中,而X(1)也可能在其它处理器上。另外,还可能需要同步或其它的跨处理器操作。

当所涉及的语句之一是一个函数和子程序调用时,这一方案存在许多巧妙之处。8.2.4节将处理这些情况。

活动处理器是动态的,并且如果一条语句被重复执行,则每次执行时的活动处理器都可能是不同的。一般来说,一个HPF结构(包括扩展)可能仅对活动集进行限制,并不对其进行扩展。但是,如果原始的活动集被划分成几个互相独立的集合,则所有的划分可能同时执行。这恰好就是TASK_REGION结构(见8.4节)如何工作的。

一些额外的术语同活动处理器的概念结合在一起时很有用的。不在活动集中出现的处理器被称为是被动的。(注意,一个处理器可能对于一条语句是被动的,而对于另一条语句是活动的。这一点在TASK_REGION中是很普通的)同时包括活动和被动的处理器集合被称为全体处理器集合。最后,有时有必要查询活动处理器集合的特性;这一点可通过所认可扩展的内部函数ACTIVE_NUM_PROCS和ACTIVE_PROCS_SHAPES来完成,见10.1节

对用户的建议:8.4节提出了系统在执行其它计算时使用被动处理器的可能性。这些可以被称之为被动聚集处理器。(对用户的建议结束)

基本原理:全力缩小活动处理器集合首先可能看起来很奇怪。但是,HPF的设计假定执行开始时所有的处理器都可以获得。例如,实现DISTRIBUTE时需要关于处理器数目(为确定块的大小)及其特性(为分配存储器和执行数据移动)的信息。因此,执行模型使用一个能够动态细分的静态处理器集合。(基本原理结束)

8.1.1 活动处理器怎样与数据映射相互影响

本分节解释了活动(被动)处理器集合与显式映射数据之间的相互影响。一种比较粗糙的方法是存储单元的分配必须在本地做;即,如果一个处理器存储数组的一部分,则当该数组创建时,此处理器必须是活动的。这一规则的意义包括:

从本地和全局变量的的处理中,很显然在定义它们时需要参照两类处理器排列。

一类是全体处理器排列,它主要用于全局数据的定义。这些排列描述了所有变量处理器集合(的一部分),包括活动的和被动的。由于它们总是描述相同的处理器,这些作为引用的固定点,允许一致性的定义。处理器指令(规则H209)缺省定义了一个全体处理器排列。为了提供活动处理器,对2.6节的规则作了两点细微的改变:

在这两种情况中,唯一的改变是增加了“全体”这个词。这样就可以避免混淆全体处理器排列和下面所定义的活动处理器排列间的对应关系。

活动处理器排列仅描述了定义排列时活动的那些处理器。它们被用于映射本地变量。为将一个处理器排列定义成活动的,我们可以使用combined-directive-extended(H701)中的ACTIVE选项。另外,我们还可以使用ACTIVE属性的语句形式:

 H801 active-directive is ACTIVE processors-name

这两种形式的例子是:

 !HPF$ PROCESSORS, ACTIVE :: P(NP/4,4)
 !HPF$ PROCESSORS Q(NP)
 !HPF$ ACTIVE Q

就象全局排列一样,对于活动处理器排列的使用也有一些修改过的规则:

注意活动处理器排列中的元素可能少于NUMBER_OF_PROCESSORS();这反映了限制活动处理器集合的方法。另外还要注意在两个活动处理器排列被认为是同一个之前,有一个附加的条件;这一点反映了活动处理器集合的动态特性。

对于没有SAVE属性的显式映射的本地变量,定义时必须将变量的所有元素映射到活动处理器上。这一说明包括如下几种情况:

无论在哪种情况中,活动处理器的确定都是在说明DISTRIBUTE和ALIGN时。即,ALLOCATABLE变量映射指令的说明是在分配该变量空间时;而其它变量的映射说明是在对其进行定义时。另外还要注意确定一个处理器是否是活动的这一行为。特别是,如果程序中没有包含修改程序活动处理器集合的ON指令,则所有的处理器总是活动的且所有的DISTRIBUTE指令都可以使用缺省全体排列。

在显式映射全局变量出现的地方,它们必须具有一致的映射。因此,要求全局变量被映射到全体处理器排列上。考虑下列几种情况:

注意,对于隐式(例如,省略)ONTO子句的解释不同于本地和全局变量;全局变量可以使用任意处理器作为它们的缺省集合,而本地变量只能使用活动处理器。全体处理器集合的确定是在说明DISTRIBUTE和ALIGN时,但是由于HPF不支持动态处理器的创建和删除,因此这一点并不重要。另外还要注意,由于全体处理器排列对于PROCESSORS指令是缺省的,因此当引入活动处理器时无须修改全局变量的映射。

必须使用上面的规则将哑参定义为本地变量。如8.2.4节所解释的,这么做的结果是哑参总是被存储在活动处理器集合上。其它的变量,特别是子程序的局部变量,可以与哑参对准并在活动处理器集合上分配空间。

无论何时进入作用域范围之内,具有SAVE属性的变量都必须被一致映射。因此,它们的作用同全局变量一样并遵循全局变量的规则。

8.1.2 活动处理器的其它约束

除定义之外,当活动处理器与全体处理器不匹配时,一些其它的结构还要受约束。一般来说,这些约束的意图是保证执行一个操作时所需的所有处理器都是活动的。特别是,分配或释放映射到一个处理器上的存储空间需要该处理器的合作。为此,我们对于在一个较小(非全体)活动处理器集合上执行的动作提出了一些约束。

对于REDISTRIBUTE指令,活动处理器集合必须包括:

从效率上,这意味着REDISTRIBUTE的所有数据移动都发生在活动处理器上;另外,事先拥有分配子(或与其对准的任何变量)的处理器可以释放内存,同时现在拥有分配子的处理器可以为其分配内存。

类似地,对于REALIGN指令,活动处理器集合必须包括在REALIGN之前存储分配子元素的所有处理器以及在REALIGN之后将要存储分配子元素的所有处理器。

对于创建显式映射变量的ALLOCATE语句,活动处理器集合必须包括用于分配变量的映射指令所使用的处理器。分配变量的根本对准目标可分为三类:

对于释放显式映射变量的DEALLOCATE语句,活动处理器必须包含拥有该变量任意元素的所有处理器。另外,对于被释放变量的根本对准目标存在三种情况:

基本原理:分配存储的操作需要拥有该存储的所有处理器之间的合作。因此当映射到它们上的变量被定义或分配空间时,它们必须是活动的。这些所适用的最一般情况是来自于所调用的子程序的ON子句。

这些约束的其它描述是:

(基本原理结束)

对实现者的建议:这些约束保证了ON块内的HPF数据分配指令在实现时无须依赖于当前进程组外的通信。它们保证了当变量产生时,需要分配存储空间的处理器是活动的。(对实现者的建议结束)


Copyright: NPACT BACKWARDFORWARD