Sun Studio 12: OpenMP API ユーザーズガイド

5.4 自動スコープ宣言結果の確認

コンパイラのコメント」を利用して、詳細な自動スコープ宣言結果を調べたり、自動スコープ宣言が失敗したために直列化された並列領域がないか確認したりできます。

コンパイルで -g が付けられていると、コンパイラはインラインコメントを生成します。このコメントは、 次に示すように er_src を使って表示できます (er_src コマンドは、Sun Studio ソフトウェアの一部として提供されています。詳細は、er_src(1) のマニュアルページまたは『プログラムのパフォーマンス解析』を参照してください)。

-xvpara コンパイルオプションを使用することからスタートすることを推奨します。自動スコープ宣言の失敗があると、 次のような警告メッセージが出力されます。


例 5–1 -vpara を使ったコンパイル


%cat t.f
      INTEGER X(100), Y(100), I, T
C$OMP PARALLEL DO DEFAULT(__AUTO)
      DO I=1, 100
         T = Y(I)
         CALL FOO(X)
         X(I) = T*T
      END DO
C$OMP END PARALLEL DO
      END
%f95 -xopenmp -xO3 -vpara -c t.f
"t.f", 2 行目: 警告: 並列領域は単一スレッドで実行されます
     次の変数の自動スコープ宣言に失敗したため:
     - x

f95 では -vparacc では -xvpara 付きでコンパイルします (CC では、まだこのオプションが実装されていません)。


例 5–2 コンパイラのコメントの見方


%cat t.f
      INTEGER X(100), Y(100), I, T
C$OMP PARALLEL DO DEFAULT(__AUTO)
      DO I=1, 100
         T = Y(I)
         X(I) = T*T
      END DO
C$OMP END PARALLEL DO
      END

%f95 -xopenmp -xO3 -g -c t.f
%er_src t.o
ソースファイル: ./t.f
オブジェクトファイル: ./ot.o
ロードオブジェクト: ./t.o

     1. INTEGER X(100), Y(100), I, T

次のソースの OpenMP 領域にタグ R1 があります
R1 中の SHARED と自動スコープ宣言された変数: x, y
R1 中の PRIVATE と自動スコープ宣言された変数: t, i
R1 中の非公開変数: i, t
R1 中の共有変数: y, x
     2. C$OMP PARALLEL DO DEFAULT(__AUTO)
       <関数: _$d1A2.MAIN_>
次のソースのループにタグ L1 があります
L1 は明示的なユーザー指令で並列化されました
L1 並列ループ本体内のコードは 0 個の内側のループとともに関数 _$d1A2.MAIN_ 内に置かれました
次のループの M-function 内のコピーにタグ L2 があります
L2 は定常サイクル数 = 3 でスケジュールされました
L2 は 4 回展開されました
L2 には、1 回の繰り返しで 0 個の load、0 個の store、2 個の prefetch、0 個の FPadd、0 個の FPmul、0 個の
FPdiv があります
L2 には、1 回の繰り返しで 1 個の int-load、1 個の int-store、4 個の alu-op、1 個の mul、0 個の int-div、1
個の shift があります
     3. DO I=1, 100
     4. T = Y(I)
     5. X(I) = T*T
     6. END DO
     7. C$OMP END PARALLEL DO
     8. END

次に、自動スコープ宣言の仕組みを示すより複雑な例を紹介します。


例 5–3 より複雑な例


 1.      REAL FUNCTION FOO (N, X, Y)
 2.      INTEGER       N, I
 3.      REAL          X(*), Y(*)
 4.      REAL          W, MM, M
 5.
 6.      W = 0.0
 7.
 8. C$OMP PARALLEL DEFAULT(__AUTO)
 9.
10. C$OMP SINGLE
11.       M = 0.0
12. C$OMP END SINGLE
13.
14.       MM = 0.0
15.
16. C$OMP DO
17.       DO I = 1, N
18.          T = X(I)
19.          Y(I) = T
20.          IF (MM .GT. T) THEN
21.             W = W + T
22.             MM = T
23.          END IF
24.       END DO
25. C$OMP END DO
26.
27. C$OMP CRITICAL
28.       IF ( MM .GT. M ) THEN
29.          M = MM
30.       END IF
31. C$OMP END CRITICAL
32.
33. C$OMP END PARALLEL
34.
35.      FOO = W - M
36.
37.      RETURN
38.      END

関数 FOO() には並列領域が 1 つあり、この並列領域には、SINGLE 構文とワークシェアリングの DO 構文、CRITICAL 構文がそれぞれ 1 つあります。こうした OpenMP 並列構文をすべて無視した場合、並列領域内のコードが行うのは、次のことです。

  1. 配列 X 内の値を配列 Y にコピーします。

  2. X 内の正の最大値を検出し、その値を M に格納します。

  3. X の一部要素の値を変数 W に蓄積します。

コンパイラが前述の規則に従って、この並列領域内の変数に適切なスコープを発見する仕組みをみてみましょう。

前述の並列領域では、INMMTWMX、および Y という変数が使用されています。コンパイラは次のことを決定します。