このサンプルの GAP レポートは、並列化を有効にするために -parallel オプションを使用することを推奨しています。コマンドラインから make gap_par_report を実行するか、以下のコマンドを実行します。
icpc -c -guide -parallel scalar_dep.cpp
コンパイラーは次のレポートを出力します。
GAP レポート記録開始 Wed Jul 28 14:33:09 2010 scalar_dep.cpp(51): リマーク #30523: (PAR) 行 51 のループ は、次の変数への条件付き代入があるため並列化できません: b。 このループを並列化するには、この変数を各反復の最初で無条件に初期化します。 [確認] ループの各反復で変数の値を読み取る場合は、同じ反復でそれ以前に書き込まれた値でなければなりません。 [別の方法] "#pragma parallel private(b)" を使用してループを並列化します。 [確認] 前述の条件をすべて満たしていなければなりません。 scalar_dep.cpp(51): リマーク #30525: (PAR) 行 51 のループのトリップカウントが 188 よりも大きい場合は、"#pragma loop count min(188)" を使用してこのループを並列化できます。 [確認] ループの反復回数が 188 以上であることを確認してください。 このコンパイルセッションで出力されたアドバイス・メッセージの数: 2。 GAP レポート記録終了
GAP レポートでは、リマーク #30523 は、変数 b が条件付きで割り当てられるため、行番号 51 のループが並列化できないことを示しています。リマーク #30525 は、コンパイラーがループを並列化するには、ループのトリップカウントが 188 以上でなければならないことを示しています。
GAP の推奨内容が適切であるこを確認したら、必要な変更を行います。プログラムのセマンティクスは変更しないでください。
このループについては、GAP が推奨するように、条件付きコンパイルがループの並列化とベクトル化を有効にします。
#ifdef TEST_GAP #pragma loop count min (188) for (i=0; i<n; i++) { b = A[i]; if (A[i] > 0) {A[i] = 1 / A[i];} if (A[i] > 1) {A[i] += b;} } #else for (i=0; i<n; i++) { if (A[i] > 0) {b=A[i]; A[i] = 1 / A[i]; } if (A[i] > 1) {A[i] += b;} } #endif }
ループが並列化/ベクトル化されたことを確認するには:
コンパイラー・オプション -vec-report1 -par-report1 を追加します。
適切なコードパスがコンパイルされるように条件定義 TEST_GAP を追加します。
コマンドラインから make final を実行するか、以下のコマンドを実行します。
icpc -c -parallel -DTEST_GAP -vec-report1 -par-report1 scalar_dep.cpp
コンパイラー・オプション -vec-report および -par-report は次の結果を出力します。プログラムがベクトル化され、並列化されたことを示しています。
scalar_dep.cpp(43) (列 3): リマーク: ループが自動並列化されました。 scalar_dep.cpp(43) (列 3): リマーク: ループがベクトル化されました。 scalar_dep.cpp(43) (列 3): リマーク: ループがベクトル化されました。
-guide、-vec-report、および -par-report コンパイラー・オプションの使用に関する詳細は、ユーザー・リファレンス・ガイドの「コンパイラー・オプション」を参照してください。
このチュートリアルでは、コンパイラーが自動並列化を通じてどのように最適化ソリューションをガイドするかを見てきました。以上で、ガイド付き自動並列処理のチュートリアルは終了です。
© 2010 Intel Corporation. 無断での引用、転載を禁じます。