OpenMP* のリダクション操作

OpenMP* のリダクションは、共有数値変数のインクリメントや配列の共有数値変数への累積など、単純な操作に適しています。リダクション操作を実装するには、reduction 節を並列領域内に追加し、指定された操作と変数を使用して並列に合計操作を行うことをコンパイラーに指示します。

ヒント

OpenMP* 並列フレームワークを使用してコードを書き直した後、インテル® Advisor でパフォーマンスを解析できます。Vectorization and Code Insights (ベクトル化とコードの調査) パースペクティブを使用して、OpenMP* コードがどの程度ベクトル化されているか解析するか、Offload Modeling (オフロードのモデル化) パースペクティブで GPU でのパフォーマンスをモデル化できます。

次のようなアノテート付きの 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

関連情報