MASTER 領域での OpenMP* PRIVATE 変数の変更

PRIVATE 変数は MASTER 領域内で変更してはなりません。

この使用方法は、通常、エラーまたは OpenMP* の誤った使用を示します。MASTER 宣言子はマスタースレッドによってのみ実行されるブロックをマークします。並列領域のほかのすべてのスレッドはマスターブロックをスキップします。PRIVATE 節は並列領域の入口でスレッドごとに複製される変数を指定します。

次の 2 つの可能性が考えられます。1 つ目は、マスタースレッドによって書き込まれた値が MASTER 領域外のどの文にも影響しない場合です。この場合、この変数を PRIVATE に指定する理由はありません。PRIVATE 変数はすべてのスレッドに対して複製されますが、 その変数がマスタースレッドによってのみ使用される場合、ほかのスレッドに対してコピーを作成する必要はないでしょう。2 つ目は、マスタースレッドによって書き込まれた値が MASTER 領域外の文に影響する場合です。この場合、MASTER 領域外の文をマスタースレッドが実行した場合と、別のスレッドが実行した場合では動作をが異なります。これは、すべての OpenMP* プログラムは並列モードとシリアルモードで実行した場合に同じ結果を生成するという原則に反します。そのため、この使用法法は誤っているか、非効率的です。

ID

問題箇所

説明

1

OpenMP* の使用方法に関するエラー

変数が代入された場所

2

OpenMP* 宣言

MASTER 宣言子の場所


// Example adapted from A.15.1c from OpenMP* 3.0 Specification
// Copyright (C) 1997-2008 OpenMP Architecture Review Board
// Here the master thread keeps track of how many iterations
// have been executed and prints out a progress report.
// This example has been modified to add a private clause
// on the first #pragma.  This is an unnecessary inefficiency,
// because the use of the master region implies that c is
// not used by other threads.  Therefore the other threads do not
// need to have their own copies created by the PRIVATE clause.

#include <stdio>

extern float average(float,float,float);
void a15( float* x, float* xold, int n, float tol )
{
    int c, i, toobig;
    float error, y;
    c = 0;
    #pragma omp parallel private(c) // bad: c should not be private
    {
        do {
            #pragma omp for private(i)
            for( i = 1; i < n-1; ++i ) {
               xold[i] = x[i];
            }
            #pragma omp single
            {
                toobig = 0;
            }
            #pragma omp for private(i,y,error) reduction(+:toobig)
            for( i = 1; i < n-1; ++i ) {
                y = x[i];
                x[i] = average( xold[i-1], x[i], xold[i+1] );
                error = y - x[i];
                if( error > tol || error < -tol ) ++toobig;
            }
            #pragma omp master
            {
                ++c; // c used in master region
                printf( "iteration %d, toobig=%d\n", c, toobig );
            }
        } while( toobig > 0 );
    }
}
        

Note icon

この例は、OpenMP* 3.0 仕様からのもので、次のように著作権が保護されています。

© 1997-2008 OpenMP Architecture Review Board.

この資料は、OpenMP Architecture Review Board の著作権と本ドキュメントのタイトルが記載され、OpenMP Architecture Review Board の許諾に基づく転載である旨が明記されている場合に限り、無料で一部または全体を転載できます また、転載は OpenMP Architecture Review Board の許諾に基づいて行われたことを明記する必要があります。

© 2010 Intel Corporation. 無断での引用、転載を禁じます。