set_directive_loop_flatten - 2025.2 日本語 - UG1399

Vitis 高位合成ユーザー ガイド (UG1399)

Document ID
UG1399
Release Date
2026-01-22
Version
2025.2 日本語

説明

入れ子になっている内側のループを 1 つのループにフラット化して統合することで、ループのすべての反復に対してパイプライン処理を適用できるようにし、より良いレイテンシを達成することができます。

(必要に応じてループ展開を実行した後で) 最も内側のループのみをパイプライン処理できます。外側のループは、データフロー化か逐次実行のいずれかで処理する必要があります。パイプライン処理されたループの外側にあるループが逐次実行である場合、その外側ループの各反復は順に実行され、そのたびに内側ループが完全に 1 回実行されます。RTL インプリメンテーションでは、外側ループから内側ループに移動するのに 1 クロック サイクル、内側のループから外側ループに戻るのに 1 クロック サイクルが必要です。さらに、その間に内側ループのすべての反復を完了するためのレイテンシ全体が加わります。逆に、入れ子のループをフラット化すると、それらを 1 つのループとして最適化およびパイプライン処理できるようになり、外側ループの反復と、内側ループの異なる呼び出しの反復が、パイプラインで重なって実行できるようになります。一般的に、ループのフラット化はパフォーマンスを向上させますが、次の注意点があります。

  • フラット化は常に実現できるわけではなく、特定のコーディング スタイルに従う必要があります。
  • 場合によっては、外側ループ内の演算や依存関係によって、タイミングやさらには II が低下することがあります。

ループ階層内の一番内側にあるループの本体に set_directive_loop_flatten プラグマを適用します。この方法でフラット化できるのは、(必要に応じて関数のインライン展開やループ展開を実行した後の) 完全な入れ子のループ、またはほぼ完全な入れ子のループのみです。

完全な入れ子のループ
  • 最内ループ以外の各ループの本体には、1 つのサブループのみが含まれており、その他の命令は含まれていません。
ほぼ完全な入れ子のループ
  • 最内ループ以外の各ループの本体には、1 つのサブループのみが含まれており、その他の制御フローは含まれていません。
  • 最内ループ以外の各ループの本体には、ループを含む関数呼び出しを含めないようにする必要があります。

ほぼ完全な入れ子のループの場合、コンパイラは、2 つのループの間に存在する命令を自動的に最も内側のループに移動し、ループが完全な入れ子構造になるようにします。

さらに、フラット化を可能にするために、次のような要件があります。

  • 各ループは、while ループではなく for ループにする必要があり、break 文は含めないようにする必要があります。
  • 各ループのトリップカウントは、ループをフラット化する前にコンパイラが計算可能である必要があります (ただし、トリップカウントは定数である必要はありません)。典型的なコーディング スタイルは次のとおりです。
    • ループ カウンターを定数でインクリメントするループ。
    • ループ カウンターの下限値と上限値は、フラット化するループに依存しないものである必要がある (それらはループ不変でなければならない)。

フラット化できない例として、内側ループのトリップカウントが外側ループのカウンターに依存しているループがあります。

不完全な入れ子のループ (つまり、ループ内に複数のサブループや制御フローが含まれる場合) は、コンパイラによってフラット化することはできません。この場合、コードを手動で再構築することでフラット化を実行する必要があります。具体的には、最も内側のループに命令を移動するか、内側ループを展開して、上位に完全な入れ子のループを作成します。

構文

set_directive_loop_flatten [OPTIONS] <location>
  • <location>: 場所 (最内ループ) を function[/label] の形式で指定します。

オプション

-off または off=true

オプションのキーワードで、loop_flatten off を含むループとそのサブループ (存在する場合) がフラット化されないようにします。

重要: LOOP_FLATTEN プラグマまたは指示子を使用すると、最適化がイネーブルになります。-off を使用すると、ディスエーブルになります。

関数 foo 内の loop_1 と、ループ階層でこれより上にあるすべてのループ (完全またはほぼ完全) を 1 つのループにフラット化します。プラグマを loop_1 の本体に記述します。

set_directive_loop_flatten foo/loop_1

関数 fooloop_2 でループがフラット化されないようにします。プラグマを loop_2 の本体に記述します。

set_directive_loop_flatten -off foo/loop_2

より詳しい例については、対応する pragma HLS loop_flatten を参照してください。