OpenMP* PRIVATE 変数への領域外アクセス

OpenMP* PRIVATE 変数が領域範囲外でアクセスされています。

OpenMP* では、PRIVATE 節により効率的に名前付き変数の参照をスレッド・プライベート・コピー (一時変数) の参照に置換できます。この一時変数は、PRIVATE 節を含む OpenMP* 構造範囲内でのみ有効です。プロシージャー呼び出しにより制御が構造外に移動され、そのプロシージャーで同じ名前の変数にアクセスした場合は、 この一時変数ではなく、外部変数が参照されます。この問題は、PRIVATE 節の意図に反するものであり、これにより、プログラムが並列モードとシーケンシャル・モードで異なる動作をします。

また別の見方として、PRIVATE 節が OpenMP* 構造の静的スコープ内でのみ有効になっていますが、動的スコープ全体で有効にする必要があることを示しています。

構造から呼び出されたサブルーチンで PRIVATE 変数にアクセスすることは可能ですが、ポインターまたは参照パラメーターを介したアクセスに限定されます。この場合、参照パラメーターまたはポインターはスレッド・プライベートな一時変数を参照します。唯一の規則として、呼び出されたサブルーチンではこの一時変数に名前でアクセスすることはできません。

ID

問題箇所

説明

1

OpenMP* 宣言

PRIVATE 節の場所

2

メモリー書き込み

PRIVATE 変数が代入された場所


#include <stdlib.h>
#include <omp.h>

int a[1000];
int k = 0;

// subroutine accesses k as global variable
// can't call this from a region where k is privatized
int evilsub(int val)
{
    k = val + 1;
    return k;
}

int main(int argc, char **argv)
{
    int i;

#pragma omp parallel for firstprivate(k)
    for (i = 0; i < 1000; i++) {
        a[i] = evilsub(k);
        k = k + 2;
    }
    return 0;
}
        

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