配列をスカラーに変形する計算のことを「縮約操作」と呼びます。典型的な縮約操作は、ベクトルの要素の合計や積です。 縮約操作は、ループ内の計算が反復にまたがって累積的に変数を変更しないという基準には反するものです。
例: ベクトルの要素の合計を縮訳する
s = 0.0 do i = 1, 1000 s = s + v(i) end do t(k) = s |
しかし、一部の操作では、並列化を妨げるのが縮約だけの場合は、この基準にかかわらず並列化できます。共通の縮約操作が頻繁に発生するので、コンパイラはこれらの操作を特別なケースであると認識し、並列化します。
-reduction コンパイラオプションが -autopar か -parallel とともに指定されていなければ、縮約操作の認識は、自動並列化解析の中には含まれません。
並列化可能なループが表 10–2 にリストされた縮約操作のいずれか 1 つを持つ場合、-reduction が指定されていれば、コンパイラはそのループを並列化します。
次の表に、f77 および f95 が認識する縮約操作をリストします。
表 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 |
MIN 関数と MAX 関数はすべての形式で認識されます。
次の条件のため、浮動小数点の合計や積の縮約操作が不正確になることがあります。
計算が並列実行されるときの順序が、1 つのプロセッサ上で逐次実行されるときの順序と違う場合
計算の順序が、浮動小数点数の合計や積に影響を与えた場合。ハードウェア浮動小数点の加算や乗算は結合則を満たしません。 どのように演算対象が関連付られているかによって、丸め、オーバーフロー、アンダーフローが発生する可能性があります。たとえば、(X*Y)*Z と X*(Y*Z) は、数値的には意味が違う可能性があります。
状況によって、エラーが受け付けられない場合があります。
例: 丸めの例です。-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 ) ! n 個の -1 と +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 個の乱数の合計を示します。
プロセッサの数 |
出力 |
---|---|
1 |
s = 0.568582080884714E+02 |
2 |
s = 0.568582080884722E+02 |
3 |
s = 0.568582080884721E+02 |
4 |
s = 0.568582080884724E+02 |
この状況では、丸めの誤差はおよそ 10-14 なので、この乱数のデータは容認できます。詳細は、『数値計算ガイド』を参照してください。