インテル® C++ コンパイラー 18.0 デベロッパー・ガイドおよびリファレンス

OpenMP* の例

次の例では、いくつかの OpenMP* 機能の使用方法を示します。

単純な差分演算子

この例は、各繰り返しごとにワーク量が異なる単純な並列ループを示したものです。負荷のバランスを向上させるため、動的スケジュールを使用しています。

並列領域の最後に暗黙的な barrier があるため、fornowait が含まれています。

void for1(float a[], float b[], int n) {
  int i, j;
  #pragma omp parallel shared(a,b,n) {
   #pragma omp for schedule(dynamic,1) private (i,j) nowait
    for (i = 1; i < n; i++)
       for (j = 0; j < i; j++)
         b[j + n*i] = (a[j + n*i] + a[j + n*(i-1)]) / 2.0;
  } 
}

2 つの差分演算子: for ループバージョン

例では、fork/join のオーバーヘッドを減らすために融合される 2 つの並列ループを使用します。2 番目のループで使用するすべてのデータは最初のループで使用されるすべてのデータと異なるため、最初の omp for プラグマには、nowait 節が含まれています。

void for2(float a[], float b[], float c[], float d[], int n, int m) {
  int i, j;
  #pragma omp parallel shared(a,b,c,d,n,m) private(i,j) {
    #pragma omp for schedule(dynamic,1) nowait
    for (i = 1; i < n; i++)
      for (j = 0; j < i; j++)
        b[j + n*i] = ( a[j + n*i] + a[j + n*(i-1)] )/2.0;
    #pragma omp for schedule(dynamic,1) nowait
    for (i = 1; i < m; i++)
      for (j = 0; j < i; j++)
        d[j + m*i] = ( c[j + m*i] + c[j + m*(i-1)] )/2.0;
  } 
}

2 つの差分演算子: sections バージョン

例では、omp sections プラグマの使用方法を示します。ロジックは、前述の omp for の例と同じですが、omp for の代わりに omp sections を使用します。ここでは、2 つの作業単位しかないため、スピードアップは、2 が限度です。前述の例では、作業単位は (n-1) + (m-1) です。

void sections1(float a[], float b[], float c[], float d[], int n, int m) {
  int i, j;
  #pragma omp parallel shared(a,b,c,d,n,m) private(i,j) {
    #pragma omp sections nowait {
      #pragma omp section
       for (i = 1; i < n; i++)
         for (j = 0; j < i; j++)
           b[j + n*i] = ( a[j + n*i] + a[j + n*(i-1)] )/2.0;
      #pragma omp section
       for (i = 1; i < m; i++)
         for (j = 0; j < i; j++)
           d[j + m*i] = ( c[j + m*i] + c[j + m*(i-1)] )/2.0;
     }
   } 
}

共有スカラーの更新

この例では、共有配列 a の要素を更新する single 構造の使用方法を示します。最初のループの後にくるオプションの nowait 節は取り除かれています。これは、single 構造に進む前にループの最後で待機する必要があるためです。

void sp_1a(float a[], float b[], int n) {
  int i;
  #pragma omp parallel shared(a,b,n) private(i) {
    #pragma omp for
      for (i = 0; i < n; i++)
        a[i] = 1.0 / a[i];
      #pragma omp single
        a[0] = MIN( a[0], 1.0 );
      #pragma omp for nowait
      for (i = 0; i < n; i++)
      b[i] = b[i] / a[i];
   } 
}