Sun Studio 12:Fortran 编程指南

10.2.4 具有约简操作的自动并行化

将一个数组转换为一个标量的计算称为约简操作。典型的约简操作有矢量元素的求和或求积。违反循环中计算标准的约简操作不能在各次迭代间以累积方式改变标量变量。

示例:向量元素的约简求和:


      s = 0.0
      do i = 1, 1000
        s = s + v(i)
      end do
      t(k) = s

但是,对于某些操作,如果约简是阻止并行化的唯一因素,仍然可以对循环进行并行化。常见约简操作出现频率很高,因而编译器能够将其视为特例进行并行化。

自动并行化分析不包括约简操作的识别,除非随 -autopar-parallel 一同指定了 -reduction 编译器选项。

如果某一可并行化的循环包含表 10–2 中列出的某一项约简操作,则当指定了 -reduction 时,编译器将会对其进行并行化。

10.2.4.1 识别的约简操作

下表列出了编译器识别的约简操作。

表 10–2 识别的约简操作

数学运算 

Fortran 语句模板 

求和 

s = s + v(i)

求积 

s = s * v(i)

点积 

s = s + v(i) * u(i)

最小值 

s = amin( s, v(i))

最大值 

s = amax( s, v(i))

OR

do i = 1, n

b = b .or. v(i)

end do

AND

b = .true.

do i = 1, n

b = b .and. v(i)

end do

非零元素计数 

k = 0

do i = 1, n

if(v(i).ne.0) k = k + 1

end do

识别所有形式的 MINMAX 函数。

10.2.4.2 数值准确性和约简操作

由于以下原因,浮点型数字的求和或求积约简操作可能不准确:

在一些情况下,该误差是不能接受的。

示例:舍入,求介于 –1 和 +1 之间的 100,000 个随机数之和:


demo% cat t4.f
      parameter ( n = 100000 )
      double precision d_lcrans, lb / -1.0 /, s, ub / +1.0 /, v(n)
      s = d_lcrans ( v, n, lb, ub ) ! Get n random nos. between -1 and +1
      s = 0.0
      do i = 1, n
        s = s + v(i)
      end do
      write(*, ’(" s = ", e21.15)’) s
      end
demo% f95 -O4 -autopar -reduction t4.f

结果会随着处理器的个数而变化。下表展示了介于 – 1 和 +1 之间的 100,000 个随机数之和。

处理器数 

输出 

s = 0.568582080884714E+02

s = 0.568582080884722E+02

s = 0.568582080884721E+02

s = 0.568582080884724E+02

在这种情况下,对于随机开始的数据而言,10-14 阶的舍入误差是可以接受的。有关更多信息,请参见 Sun《数值计算指南》。