OpenMP* のリダクションは、共有数値変数のインクリメントや配列の共有数値変数への累積など、単純な操作に適しています。リダクション操作を実装するには、reduction 節を並列領域内に追加し、指定された操作と変数を使用して並列に合計操作を行うことをコンパイラーに指示します。
次のようなアノテート付きの C/C++ シリアルコードについて考えてみます。
int i, n=500000;
float *array, total=0.0;
...
for (i=0; i <n ; ++i
{
ANNOTATE_LOCK_ACQUIRE(0);
total+ = array[i];
ANNOTATE_LOCK_RELEASE(0);
}
...
リダクションを行うため、#include <omp.h> と #pragma omp parallel for reduction を追加した並列 C/C++ コード:
#include <omp.h> // .dll を検出できないロード時の問題を解決します
int i, n=500000;
float *array, total=0.0;
...
#pragma omp parallel for reduction(+:total)
for (i=0; i <n ; ++i
{
total+ = array[i];
}
...
次のようなアノテーション付きの Fortran シリアルコードについて考えてみます。
integer(4) n
real(4) array(50000), total = 0.0
n = 500000
...
do i=1, n
call annotate_lock_acquire(0)
total = total + array(i)
call annotate_lock_release(0)
...
end do
use omp_lib、!$omp parallel do reduction(+:total)、および !$omp end parallel do を追加した Fortran コードを考えてみます。
use omp_lib
integer(4) n
real(4) array(50000), total = 0.0
n = 500000
...
!$omp parallel do reduction(+:total)
do i=1, n
total = total + array(i)
!$omp end parallel do
...
end do