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. 無断での引用、転載を禁じます。