Sun Studio 12:Fortran 编程指南

10.1.3 数据依赖性问题

不是所有的循环都可并行化。在多个处理器上以并行方式运行循环通常会导致迭代执行次序紊乱。而且,只要循环中存在数据依赖性,以并行方式执行循环的多个处理器便有可能相互干扰。

会引起数据依赖性问题的情况包括递归、约简、间接寻址以及依赖于数据的循环迭代。

10.1.3.1 依赖于数据的循环

您可以重新编写循环来消除数据依赖性,使其可以并行化。但需要进行大量的重构工作。

以下是一些通用规则:

这些是进行并行化的一般条件。在确定是否并行化循环时,编译器的自动并行化分析会考虑附加条件。但是,可以使用指令显式地强制并行化循环,甚至是那些包含抑制因素和产生错误结果的循环。

10.1.3.2 递归

在循环的某一次迭代中设置并在后续迭代中使用的变量会导致产生交叉迭代依赖性或递归。循环中的递归要求迭代以正确顺序执行。例如:


   DO I=2,N
      A(I) = A(I-1)*B(I)+C(I)
   END DO

必须在上一迭代中计算出 A(I) 的值,方能在当前迭代中(作为 A(I-1))使用。要产生正确的结果,迭代 I 必须先完成,迭代 I+1 方可执行。

10.1.3.3 约简

约简操作可将数组中的元素约简为单个值。例如,在对数组元素求和并送入单个变量时,需要在每次迭代时更新该变量:


   DO K = 1,N
     SUM = SUM + A(I)*B(I)
   END DO

如果以并行方式运行该循环的每个处理器均取得了迭代的一些子集,这些处理器将会相互干扰,从而覆盖 SUM 中的值。为使之正常工作,每个处理器每次必须执行一次求和,但顺序并不重要。

编译器会将某些常见的约简操作视为特例进行处理。

10.1.3.4 间接寻址

如果向在循环中用下标(下标值未知)标出的数组存储数据,会导致循环依赖性。例如,如果在索引数组中存在重复的值,间接寻址会依赖于顺序:


   DO L = 1,NW
     A(ID(L)) = A(L) + B(L)
   END DO

在示例中,ID 中重复的值会造成 A 中的元素被覆盖。在串行情况下,最后存储的是最终值。在并行情况下,顺序是不确定的。所使用的 A(L) 值(旧的或更新后的)依赖于顺序。