次の方法で共有


A.19 動作共有ディレクティブの正しくない入れ子の例

このセクションでは、例を使用して、ディレクティブの入れ子規則について説明します。ディレクティブの入れ子の詳細については、33 ページのセクション 2.9 を参照してください。

次の例では、内側と外側の for ディレクティブが入れ子になって、同じ parallel ディレクティブにバインドされているため、規則違反になります。

void wrong1(int n)
{
  #pragma omp parallel default(shared)
  {
      int i, j;
      #pragma omp for
      for (i=0; i<n; i++) {
          #pragma omp for
              for (j=0; j<n; j++)
                 work(i, j);
     }
   }
}

前述の例が動的に入れ子になった形ですが、これも規則違反です。

void wrong2(int n)
{
  #pragma omp parallel default(shared)
  {
    int i;
    #pragma omp for
      for (i=0; i<n; i++)
        work1(i, n);
  }
}

void work1(int i, int n)
{
  int j;
  #pragma omp for
    for (j=0; j<n; j++)
      work2(i, j);
}

次の例では、for ディレクティブと single ディレクティブが入れ子になって、同じ並行領域にバインドされているため、規則違反になります。

void wrong3(int n)
{
  #pragma omp parallel default(shared)
  {
    int i;
    #pragma omp for
      for (i=0; i<n; i++) {
        #pragma omp single
          work(i);
      }
  }
}

次の例も規則違反です。barrier ディレクティブが for 内にあるため、デッドロックの原因になります。

void wrong4(int n)
{
  #pragma omp parallel default(shared)
  {
    int i;
    #pragma omp for
      for (i=0; i<n; i++) {
        work1(i);
        #pragma omp barrier
        work2(i);
      }
  }
}

次の例も規則違反です。クリティカル セクションには一度に 1 つのスレッドしか入れないため、barrier がデッドロックの原因になります。

void wrong5()
{
  #pragma omp parallel
  {
    #pragma omp critical
    {
       work1();
       #pragma omp barrier
       work2();
    }
  }
}

次の例も規則違反です。single セクションを実行できるのは 1 つのスレッドのみであるため、barrier がデッドロックの原因になります。

void wrong6()
{
  #pragma omp parallel
  {
    setup();
    #pragma omp single
    {
      work1();
      #pragma omp barrier
      work2();
    }
    finish();
  }
}