ソフトウェアのパイプライン化 (SWP) レポートは、Itanium(R) ベース・システムでソフトウェアのパイプライン化を現在活用しているループに関する詳細な情報を提供します。さらに、レポートは、パイプライン化されていないループの理由も示します。
次のコマンド構文は、Itanium コンパイラーのコード・ジェネレーター (ECG) ソフトウェア・パイプライナー (SWP) 用の SWP レポートを生成する方法を示しています。
プラットフォーム |
構文例 |
---|---|
Linux* |
icc -c -opt-report -opt-report-phase ecg_swp swp.cpp |
Windows* |
icl /c /Qopt-report /Qopt-report-phaseecg_swp swp.cpp |
ここで、-c (Linux)、/c (Windows) は、オブジェクト・コードの生成時に停止する (リンクしない) ようにコンパイラーに指示し、-opt-report (Linux)、/Qopt-report (Windows) はレポート・ジェネレーターを起動し、-opt-report-phase ecg_swp (Linux)、/Qopt-report-phase ecg_swp (Windows) はレポートを生成するフェーズ (ecg) を示します。
Linux のみ: オプションとフェーズのスペースはオプションです。
レポートで、ソフトウェア・パイプライン中のループには、コンパイラーが SWP 用にループをスケジューリングしていたことを示す行が表示されます。-O3 (Linux) または /O3 (Windows) オプションが指定されると、SWP レポートは、ループ最適化機構によって実行されたループ変換サマリーをマージします。
このサンプルコードを -c -restrict (Linux) および /c /Qrestrict (Windows) の組み合わせを使用してコンパイルすると、サンプル SWP レポートが生成されます。サンプルレポートの内容は、この後に示されています。
例 |
---|
#define NUM 1024 void multiply_d(double a[][NUM], double b[][NUM], double c[restrict][NUM]){ int i,j,k; double temp; for(i=0;i<NUM;i++) { for(j=0;j<NUM;j++) { for(k=0;k<NUM;k++) { c[i][j] = c[i][j] + a[i][k] * b[k][j]; } } } } |
次のサンプルレポートは、上記の例を (ecg_swp フェーズを使用して) コンパイルした結果のレポートフェーズを示しています。
サンプル SWP レポート |
---|
Swp report for loop at line 8 in _Z10multiply_dPA1024_dS0_S0_ in file SWP report.cpp Resource II = 2 Recurrence II = 2 Minimum II = 2 Scheduled II = 2 Estimated GCS II = 7 Percent of Resource II needed by arithmetic ops = 100% Percent of Resource II needed by memory ops = 50% Percent of Resource II needed by floating point ops = 50% Number of stages in the software pipeline = 6 |
特定のループがソフトウェア・パイプライン化されたかどうかを素早く判断する方法の 1 つは、レポート出力で "Number of stages in the software pipeline" というフレーズを検索する方法です。このフレーズが見つかった場合、関連するループのソフトウェアのパイプライン化が成功したことを意味します。
SWP レポートの結果を理解するためには、用語と関連する概念について知っておく必要があります。次の表では、SWP レポートで使用される用語を説明します。
用語 |
定義 |
---|---|
II |
初期インターバル (II)。SWP で、ある反復の開始から次の反復の開始までのサイクル数です。SWP レポートに用語 II が含まれている場合、問題のループで SWP が成功したことを意味します。 II は、反復の数がわかっている場合に、ループを実行するサイクル数を決定する簡易計算で使用されます。ループの合計サイクル数は、約 N * Scheduled II + ステージ数 (N はループの反復の数) です。SWP のプロローグおよびエピローグの ramp-up および ramp-down を考慮しないで、SWP ループのカーネルについてのみ考慮しているので、これはあくまでも近似値です。コードを修正するとき、本来は根本的な性能係数であるソフトウェア・パイプライン中の N * Scheduled II + ステージ数を確認するべきですが、一般的には、Scheduled II が下がることを確認するほうがよいでしょう。 |
Resource II |
Resource II は、利用可能な関数ユニットの数を考慮する場合の初期インターバルを示します。 |
Recurrence II |
Recurrence II は、ループに再帰関係がある場合の初期インターバルを示します。再帰関係は、a[i] = a[i-1] (ここで、a[i] は a[i-1] がわかるまで計算できない) のようなフロー依存性と呼ばれる特別な種類のデータ依存性です。Recurrence II がゼロではなく、コードにフロー依存性がない場合、非ユニット・ストライド・アクセスまたはメモリー・エイリアシングのいずれかであることを示します。 詳細は、「コンパイラーの活用」を参照してください。 |
Minimum II |
Minimum II は、達成可能な理論上の最小初期インターバルです。 |
Scheduled II |
Scheduled II は、コンパイラーが SWP 用に実際に予定したものです。 |
number of stages |
ステージ数を示します。例えば、下記のレポート結果で、Number of stages in the software pipeline = 3 は、アセンブリーで 3 つのステージ (ロード、FMA 命令およびストア) があったことを示します。 |
loop-carried memory dependence edges |
ループ運搬のメモリー依存エッジは、コンパイラーが WAR (READ の後の WRITE) 依存を回避したことを意味します。 ループ運搬のメモリー依存エッジは、メモリー・エイリアシングに関する問題を示します。詳細は、「コンパイラーの活用」を参照してください。 |
問題を解決する最も効率的な方法は、SWP していないループを解析して、SWP を有効にするための方法を見つけることです。
コンパイラーが Loop was not SWP because... とレポートした場合、次の表で問題を緩和する推奨方法を参照してください。
レポートのメッセージ |
推奨する処理 |
---|---|
acyclic global scheduler can achieve a better schedule: => loop not pipelined |
最も可能性の高い問題がメモリー・エイリアシング問題であることを示します。メモリー・エイリアシング (restrict, #pragma ivdep) を参照してください。 また、アプリケーションが非ユニットストライド方式でメモリーにアクセスしていることも示します。非ユニットストライド問題は、不自然に高い再帰 II で示されます。ループで再帰関係 (例えば、a[i] = a[i-1] + b[i]) がないことがわかっている場合、高い再帰 II (0 より大きい) は、非ユニットストライドでメモリーにアクセスしているというサインです。コードの再配置 (ループ交換) は、この問題を緩和します。 |
Loop body has a function call |
関数のインライン展開が問題の解決に役立つことを示します。 |
Not enough static registers |
ループを 2 つ以上のループに分配するべきであることを示します。 Itanium ベース・システムでは、#pragma distribute point を使用してください。 |
Not enough rotating registers |
ループ運搬の値が rotating registers (回転レジスター) を使用することを示します。ループを分配します。Itanium ベース・システムでは、#pragma distribute point を使用してください。 |
Loop too large |
ループを分配するべきであることを示します。 Itanium ベース・システムでは、#pragma distribute point を使用してください。 |
Loop has a constant trip count < 4 |
アンロールが不十分だったことを示します。ループが完全にアンロールするようにしてください。しかし、小さなループでは、ループが完全にアンロールしてもパフォーマンスに大きく影響することはありません。 |
Too much flow control |
ループ構造が複雑なことを示します。ループを単純にしてください。 |
使用されるインデックス変数型はパフォーマンスに大きく影響します。例えば、short または符号なし int のインデックス変数型を使用すると、ソフトウェアのパイプライン化が妨げられることがあります。レポートでインデックス変数が int ではないループでパフォーマンス問題が発生していることが示され、他に明らかな原因が見当たらない場合、インデックス変数を変更してみてください。
レポートの生成に使用できるオプションに関する詳細は、「最適化機構レポートの作成」を参照してください。