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();
}
}