3.2 INDEPENDENT的进一步例子 BACKWARD FORWARD


  !HPF$ INDEPENDENT
     DO I=1,10
      WRITE(IOUNIT(I),100) A(I)
     ENDDO
  100   FORMAT(F10.4)

如果对于每一个i({1,...,10},IOUNIT(I)都估算出一个不同的值,则在每次迭代上循环都要写向一个不同的I/O单元(或者一个不同的文件)。然后就可将此循环正确地描述为独立的。另一方面,如果对于所有的I,IOUNIT(I)=5,则此声明就是错误的并且本指令不符合HPF标准。

  !HPF$ INDEPENDENT, NEW(J)
  DO I = 2, 100, 2
   !HPF$ INDEPENDENT, NEW(VL, VR, UL, UR)
   DO J =2, 100, 2
    VL = P(I,J)-P(I-1,J)
    VR = P(I+1,J)-P(I,J)
    UL = P(I,J)-P(I,J-1)
    UR = P(I,J+1)-P(I,J)
    P(I,J) = F(I,J)+P(I,J)+0.25*(VR-VL+UR-UL)
   ENDDO
  ENDDO

如果没有J循环上的NEW子句,则哪一个循环都不是独立的,这是因为循环迭代的交叉执行可能导致在对P(I,J)赋值时使用VL,VR,UL,和UR其它的值,而不是同一循环迭代所计算出的那些值。可是,NEW子句指明如果每个循环迭代使用不同的存储单元就是不对的。使用这一实现使得循环迭代之间相互独立。注意由于循环步长的原因,对数组P访问没有冲突(例如,I和J总是偶数,因此I-1等,总是奇数)

当循环是嵌套时,即使所发生的归约操作被嵌套在内层循环中,也需要在INDEPENDENT外层循环中将归约变量保护起来。而且,内层循环和任何交叉循环可以是独立的也可以是不独立的。

  !嵌套循环例 1。内层循环是串行的。

   X=10
   OUTER: DO WHILE (X<1000) !此循环是串行的
    !HPF$ INDEPENDENT, NEW(J), REDUCTION(X)
   MIDDLE: DO I=1, N
    INNER: DO J=1, M
    X=X+J
   !注意,除非在归约语句中,
   !否则在这里引用X是不正确的。
   ENDDO INNER
   !注意,除非在归约语句中,
   !否则在这里引用X是不正确的。
   ENDDO MIDDLE
   PRINT *, X
  ENDDO OUTER 

因为变量X出现在循环MIDDLE的一个归约子句中,因此它在整个该循环中是一个受保护的归约变量,包括在内部循环中。如果INNER有一个INDEPENDENT指令,则在该指令的REDUCTION或NEW子句中包含X是不正确的。最外层循环不是独立的,因此X无须也不能在它的范围中且中间循环外面受保护。

NEW子句中出现的变量不能是同一循环或某一外层循环中的归约变量,但可在内层循环中将其用作一个归约变量:

 !嵌套循环例2。外层循环NEW子句。

   !HPF$ INDEPENDENT, NEW(I)
   OUTER: DO K=1,100
    !HPF$ INDEPENDENT, NEW(J,X)
    MIDDLE: DO I=1,N
     X=10
     !HPF$ INDEPENDENT, REDUCTION(X)
     INNER: DO J=1,M
      X=X+J**2
      !注意,除非在归约语句中,
      !否则在这里引用X是不正确的。
     ENDDO INNER
     Y(I)=X
    ENDDO MIDDLE
   ENDDO OUTER  

在这里,X仅能在内层循环中是一个受保护的归约变量。

   INTEGER, DIMENSION(M) :: VECTOR

   !HPF$ INDEPENDENT, REDUCTION(X,Y)
   DO I=1,N
    X(I:I+4)=X(I:I+4)+<ERR> !更新5次
    Y(VECTOR)=Y(VECTOR)+<VECTOR-EXPR)
   ENDDO

如果此循环迭代是在块方式中分配的,则编译器无须为整个数组X建立一个私有拷贝。

当一个INDEPENDENT循环活动时,如果一个语句是以归约语句的形式出现的,但被更新的变量不是一个受保护的归约变量,则程序员必须保证任意两个INDEPENDENT的迭代不会对同一位置进行更新。例如:

   !HPF$ INDEPENDENT
   DO I=1,N
    !我知道在INDX(1:N)中没有重复值
    !且X不是归约变量。
    !更新将被直接写入X(INDX(I))中
    X(INDX(I))=X(INDX(I))+F(I)
    !我也保证IF语句中的条件无论对于0
    !还是对于i的某一值都为真
    IF(A(I)>B(I)) Y=Y+1
   END DO


Copyright: NPACT BACKWARD FORWARD