ナビゲーションリンクをスキップ | |
印刷ビューの終了 | |
Oracle Solaris Studio 12.3: OpenMP API ユーザーガイド Oracle Solaris Studio 12.3 Information Library (日本語) |
スコープチェックを有効にするには、-xvpara および -xopenmp オプションを使用するとともに最適化レベルを -xO3 かそれ以上に設定してから OpenMP プログラムをコンパイルします。スコープチェックは、プログラムが -xopenmp=noopt でコンパイルされただけでは動作しません。最適化レベルが -xO3 未満の場合、コンパイラは警告メッセージを発行し、スコープチェックを行いません。
スコープチェック時には、コンパイラはすべての OpenMP 構文を確認します。いくつかの変数のスコープ宣言に問題がある場合は、コンパイラは警告メッセージを発行します。場合によっては、正しいデータ共有属性節が提案されます。
例:
例 7-1 スコープチェック
% cat t.c #include <omp.h> #include <string.h> int main() { int g[100], b, i; memset(g, 0, sizeof(int)*100); #pragma omp parallel for shared(b) for (i = 0; i < 100; i++) { b += g[i]; } return 0; } % cc -xopenmp -xO3 -xvpara source1.c "source1.c", line 10: Warning: inappropriate scoping variable 'b' may be scoped inappropriately as 'shared' . write at line 13 and write at line 13 may cause data race "source1.c", line 10: Warning: inappropriate scoping variable 'b' may be scoped inappropriately as 'shared' . write at line 13 and read at line 13 may cause data race
コンパイラは、最適化レベルが -xO3 未満の場合はスコープチェックを行いません。
% cc -xopenmp=noopt -xvpara source1.c "source1.c", line 10: Warning: Scope checking under vpara compiler option is supported with optimization level -xO3 or higher. Compile with a higher optimization level to enable this feature
次の例は、可能性のあるスコープ宣言エラーを示しています。
例 7-2 スコープ宣言エラーの例
% cat source2.c #include <omp.h> int main() { int g[100]; int r=0, a=1, b, i; #pragma omp parallel for private(a) lastprivate(i) reduction(+:r) for (i = 0; i < 100; i++) { g[i] = a; b = b + g[i]; r = r * g[i]; } a = b; return 0; } % cc -xopenmp -xO3 -xvpara source2.c "source2.c", line 8: Warning: inappropriate scoping variable 'r' may be scoped inappropriately as 'reduction' . reference at line 13 may not be a reduction of the specified type "source2.c", line 8: Warning: inappropriate scoping variable 'a' may be scoped inappropriately as 'private' . read at line 11 may be undefined . consider 'firstprivate' "source2.c", line 8: Warning: inappropriate scoping variable 'i' may be scoped inappropriately as 'lastprivate' . value defined inside the parallel construct is not used outside . consider 'private' "source2.c", line 8: Warning: inappropriate scoping variable 'b' may be scoped inappropriately as 'shared' . write at line 12 and write at line 12 may cause data race "source2.c", line 8: Warning: inappropriate scoping variable 'b' may be scoped inappropriately as 'shared' . write at line 12 and read at line 12 may cause data race
この疑似的な例は、スコープチェックによって検出される典型的なスコープ宣言エラーを示します。
縮約変数として r が指定され、この変数の演算は + となっているが、実際に行われるべき演算は * です。
PRIVATE として a が明示的にスコープ宣言されています。PRIVATE 変数には初期値がないので、行 11 の a への参照では、ガベージ値が取得されることがあります。コンパイラはこの問題を指摘し、a を FIRSTPRIVATE としてスコープ宣言するようプログラマに提案します。
変数 i はループインデックス変数です。ループインデックスがループ後に使用される場合、プログラマはこれを LASTPRIVATE として指定することもあります。 しかし、この例では、i はループ後にはまったく参照されていません。コンパイラは警告を発行し、i を PRIVATE としてスコープ宣言するようプログラマに提案します。PRIVATE を LASTPRIVATE の代わりに使用すると、パフォーマンスが向上します。
プログラマは、変数 b に対してはデータ共有属性を明示的に指定しません。OpenMP 仕様 3.0 の 79 ページ、27 - 28 行によると、b は SHARED として暗黙的にスコープ宣言されます。ただし、b を SHARED としてスコープ宣言すると、データ競合が発生します。b の正しいデータ共有属性は REDUCTION です。