ループのソフトウェア パイプライン処理 - 2023.2 日本語

AI エンジン カーネルおよびグラフ プログラミング ガイド (UG1079)

Document ID
UG1079
Release Date
2023-12-04
Version
2023.2 日本語

このセクションでは、ループのソフトウェア パイプライン処理について詳細に説明します。これは、AI エンジンをイネーブルにしてプログラムの異なる部分を同時実行するために重要な概念です。例として、次の図に 1 回の反復に合計 9 サイクルかかるループを示します。すべてを順次実行する場合からパイプライン処理して完全にオーバーラップさせる場合までを示しています。

図 1. パイプライン処理の例

これらの各例のサイクルをカウントすると、順次実行の場合は 3 つのループ反復を完全に実行するのに 27 サイクル必要ですが、部分的にオーバーラップさせたパイプラインでは 13 サイクル、完全にパイプライン処理されたループでは 11 サイクルしかかかりません。そのため、パフォーマンスの面からは完全にオーバーラップさせるパイプライン処理が最適です、ただし、リソース制約および反復間ループの依存関係により、完全にオーバーラップできない場合もあります (次の図を参照)。

図 2. パイプライン処理での依存関係

この例のプログラムは、サイクル 2 でロード A (2 x 256 ビット)、サイクル 3 でロード B (2 x 256 ビット)、サイクル 6 および 7 でループ変数 A に対する演算を実行します。この反復の残りの命令は、ループのパフォーマンス解析には重要ではありません。

このループ反復のサイクル 2 と 3 では、4 x 256 ビットのロード操作が実行されます。AI エンジンではサイクルごとに 2 つのロードしか実行できないので、必要な 4 つのロードが 2 サイクルで実行されます。これは、リソース制約と呼ばれます。この反復を含むループをパイプライン処理する場合、この制約によりオーバーラップが 2 サイクル以上に制限されます。同様に、サイクル 6 とサイクル 7 の反復間のコード依存関係により、追加のオーバーラップが阻止される場合があります。この例では、ループの次の反復を実行する前に A の値がアップデートされている必要であるため、オーバーラップが制限されます。

aiecompiler は、各ループに関して次の形式でレポートします。

注記: コアのコンパイル レポートは Work/aie/core_ID/core_ID.log に生成されます。詳細レポートを生成するには、-v オプションを使用します。
HW do-loop #397 in "testbench.cc", line 132: (loop #16) :
Critical cycle of length 2 : b67 -> b68 -> b67
Minimum length due to resources: 2
Scheduling HW do-loop #397
(algo 1a)       -> # cycles: 9
(modulo)        -> # cycles: 2 ok (required budget ratio: 1)
(resume algo)     -> after folding:  2 (folded over 4 iterations)
  -> HW do-loop #397 in "testbench.cc", line 132: (loop #16) : 2 cycles
NOTICE: loop #397 contains folded negative edges
NOTICE: postamble created
Removing chess_separator blocks (all)

上記の aiecompiler レポートでは、[Critical cycle of length] にコードの依存関係、[Minimum length due to resources] にリソース制約による最小オーバーラップ要件が示されています。algo 1a 行には、1 反復にかかる合計サイクル数が示されます。これらの数値から、最大 5 反復が同時にアクティブになり、パイプラインが形成されています。

aiecompiler では、これら 5 つのオーバーラップ反復 (現在の反復とオーバーラップされた 4 つの反復) が resume algo 行にレポートされます。さらに、開始間隔 (II)、次の反復を開始する前に 1 つの反復で実行する必要があるサイクル数 (この例では 2) を示します。

通常は、chess_prepare_for_pipelining 指示子を使用してコンパイラでソフトウェア パイプライン処理が実行されるようにするだけで充分です。ループの反復数がコンパイル時定数である場合、chess コンパイラにより最適なソフトウェア パイプラインが作成されます。

可変ループ範囲 (変数 start/end で定義) の場合、効率的なパイプライン ループ構造を作成するため、コンパイラに追加情報を供給する必要があります。これには、chess_loop_range(<minimum>, <maximum>) 指示子を使用します。

注記: ループのサイクル数が 64 サイクルを超える場合、コンパイラがそのループのパイプライン処理をディスエーブルにすることがあります。この場合、コンパイラから次のようなメッセージが表示されます。
(algo 1a)       -> # cycles: 167 (exceeds -k 64) -> no folding: 167
  -> HW do-loop #511 in "xxxx", line 794: (loop #8): 167 cycles
ループ パイプライン処理のしきい値を大きくするには、aiecompiler に次のオプションを追加します。
--Xchess="main:backend.mist2.maxfoldk=200"
重要: 詳細レポートを生成するには、Vitis IDE で次の図に示すように [Verbose] をオンにするか、コマンド ラインで aiecompiler-v オプションを使用します。
図 3. デバッグ レポートで詳細モードをイネーブルにする

aiecompiler-Xchess=main:backend.mist2.xargs=-ggraph オプションを指定すると、モジュロ スケジューリングされたループにモジュロ スケジューリング レポートを生成できます。モジュロ スケジューリング レポートは、ソフトウェア パイプライン ループに対して、*_modulo.rpt in Work/aie/core_ID/Release/chesswork/<mangled_function_name>/*.rpt (* はブロック名) という名前で生成されます。モジュロ スケジューリング レポートには、レジスタ ファイルのレジスタ ライブ範囲に関する情報も含まれます。これは、効率的でないレジスタの割り当てを見つけるのに役立ち、chess_storage を使用することにより改善できます。

コンパイルおよびリンクが完了したら、Vitis IDE で各カーネルのコンパイル ログを開くことができます。詳細は、 『AI エンジン ツールおよびフロー ユーザー ガイド』 (UG1076) を参照してください。