高位合成 (HLS) で最良の結果を得るには、デザインのマクロ アーキテクチャを改善するコード変更が必要になることが多くあります。これをしやすくするため、Vitis HLS コード アナライザーからは、タスクレベルの並列処理の可能性を視覚化し、パフォーマンスを最適化するのに必要なアーキテクチャの変更を理解できる機能が提供されています。
C シミュレーション設定 で説明されるように、HLS コンフィギュレーション ファイルで csim.code_analyzer
コマンドを有効にすると、C シミュレーション手順の一部としてコード アナライザーを実行できます。実行すると、コード アナライザー レポートが Flow Navigator の C シミュレーション ステップのレポート、または Vitis Unified IDE の [Analysis] ビューで使用できるようになります。コード アナライザーには次の機能があります。
- データフロー グラフの抽出
- コード アナライザー レポートは、最上位のステートメントがデータフロー プロセス (DFG ノード) になり、これらのプロセスのデータ依存関係がデータフロー チャネル (DFG エッジ) になるデータフロー グラフ (DFG) を抽出します。このグラフは、関数やループ本体がデータフローでない場合でも生成でき、HLS 用のプログラミング モデル で説明されるように、コードをデータフロー形式でどのように書き換えればよいかを判断するのに役立ちます。
- パフォーマンス メトリクス
- データ量、トランザクション間隔 (TI)、スループットなどのパフォーマンス メトリクスは、コード アナライザーで決定されます。データ量とアクセス モードは、プロファイル情報に基づいて C テストベンチから決定できます。たとえば、変数 A が 32 ビット幅のポートが推論され、プロセス 2 で読み出される前にプロセス 1 で 8 Kb のデータを書き込むように決定されます。合成前にデザインを解析する場合、コード アナライザーがトランザクション間隔 (データ転送が完了するまでの時間) とチャネルのスループットを見積もります。ただし、この推論は合成前に実行されるので、合成された RTL のパフォーマンスから計算する場合よりも精度は落ちます。
- パフォーマンス ガイダンス
- HLS コンポーネントのソース コードに含まれる可能性のある主なパフォーマンス ブロッカーを特定します。これらのブロッカーには、サイクル依存やメモリ ポートの競合が含まれます。パフォーマンス ガイダンスは、デザインのパフォーマンスを制限する可能性のあるコード構造を理解したり、デザインが達成できるパフォーマンス レベルを理解するのに役立つメトリクスを特定したりするのに役立ちます。
- グラフの変換
- データフロー グラフの分解と、測定されたメトリクスと見積もられたメトリクスに基づいて、グラフが表示されるように理想的でないとわかることがあります。プロセスをマージしてグラフを修正すると、What-if タイプのデザイン確認を実行できます。グラフが変更されると、新しいアーキテクチャから新しいパフォーマンス メトリクスが決定されます。このデザイン プロセスを繰り返すことで、理想的に構築されたソリューションの青写真ができるので、それを基にソース コードをリファクタリングできます。
コード アナライザー レポートの使用
コード アナライザーを有効にして C シミュレーション コマンドを実行すると、コード アナライザー レポートが生成され、Vitis Unified IDE の [Analysis] ビューまたは Flow Navigator の [Reports] ヘッダーの下に表示できます。コード アナライザー レポートは、次の例に示すように、コンポーネントの最上位関数で定義されたプロセスとチャネルのグラフを最初に表示します。ツールバー メニューの Function セレクターを使用するか、グラフ内の展開されたプロセスで右矢印をクリックすることで、レポートの範囲を変更できます。
コード アナライザー レポートの機能は、次のとおりです。
- Graph
- レポートの [Graph] ビューは、デザインのプロセスとチャネルをデータフロー グラフで表示します。これは、DATAFLOW プラグマや指示子がソース コードに存在しなくても、その存在を推論します。各プロセスには、そのエレメントのトランザクション間隔とパフォーマンス ガイダンスが表示され、[Code] ビューを展開すると、そのエレメントのソース コードも表示できます。次の例では、合成前の解析で見積もられたパフォーマンスを表示しています。データフロー プロセス (グラフ ノード) では、TI が右上に黄色/赤色のボックスで表示されます。
- 表
- コード アナライザー レポートには、グラフの下に [Processes] と [Channels] の 2 つのタブのある表が表示されます。さまざまなエレメントの簡単なサマリが表示されるので、1 つの表で解析結果を確認できます。
- [Processes] タブにはグラフのプロセスが表示され、合成前のトランザクション間隔 (TI) の見積もり値も表示され、解析によってはデザイン ガイダンスも生成されて表示されます。
- [Channels] タブには、各プロセスに出入りするデータフロー チャネルが行別に表示されます。チャネルは、それを定義する変数の名前にちなんで命名され、ビット幅、チャネルを介して送信されるはずのデータ量、予測されるスループット、アクセス モード、プロデューサーおよびコンシューマー タスクまたはプロセスなどの変数宣言の詳細が記述されます。
- ツールバー
- コード アナライザー レポートのツールバー メニューには、レポートの設定や表示に役立つコマンドが多数用意されています。
- 概要表示
- [Overview] はグラフ全体の縮図で、グラフの個別箇所への参照が含まれており、グラフを拡大すると、その箇所を表示できます。[Overview] を使用すると、バウンダリを操作してグラフの表示を管理できます。必要であれば [Overview] を閉じてグラフのスペースを空けることもできます。
グラフの操作
デザインを開始する際には、HLS コンポーネントのソース コードを深く理解し、主要なプロセスと、これらのプロセス間の依存関係を特定する必要があります。コード アナライザーは、C シミュレーションの出力としてコードをデータフロー グラフで表示することで、これをサポートします。
コード アナライザー レポートには、各プロセスのトランザクション間隔 (TI) が表示され、最も大きな TI がヒートマップに赤い背景で表示されます。赤はデザインの問題部分を示します。ただし、このグラフで使用される合成前の見積もりは、合成後やインプリメンテーション後のメトリクスと同じ精度にはなりません。コード アナライザーを使用すると、パフォーマンスの可能性をすばやく判断し、問題を特定して解決できます。より正確な情報が必要な場合は、合成とインプリメンテーションを実行してください。
ソース コード内の連続したプロセスをマージして、デザインのさまざまなデータフロー構造を調べて、必要に応じてコードを分割して別々のプロセスに戻すことができます。1 つのプロセスを 2 つ目のプロセスにドラッグ アンド ドロップするだけで、両プロセスをマージできます。元のソース コードでは、プロセスはシーケンシャルである必要がありました。次の図は、マージされた 2 つのプロセスを示しており、コード内の SPLIT 行をクリックすると、再び分割できるようになりました。
現在のデザインに大きなボトルネックがあって、それをデータフロー領域にする場合は、グラフの焦点を関数またはループ本体に戻して、デザインの解析を続けることができます。計画的に問題解決に取り組んで、コード アナライザーを最大限に活用してください。
最終的には、コードをデータフロー形式で書き直して、コード アナライザーの結果を反映させる必要があります。通常は、プロセスを独自の関数でアウトライン化し、関数、ループ、または領域にデータフロー プラグマを追加する必要があります。このプロセスは、グラフ内のすべてのプロセスで Goto Source をクリックし、選択したソース コード上で右クリックし、Refactor を選択すると高速化できます。
ユース ケース
- 正当性
-
コード アナライザーを使用すると、正規形式 および 正規本体 で説明されるような記述の正当性の問題を、合成前にデータフロー デザイン上で特定できます。重要な問題点は、次のとおりです。
- 読み出しおよび書き込みインターフェイスは、Start ノードから開始されるチャネル、または End ノードに向かうチャネル上の "R+W" アクセスから見つけることができます。
- 複数のプロデューサー/コンシューマー違反は、チャネル名で並べ替えて、同じ変数を持つ複数のチャンネルを特定すると、表から見つけることができます。Start ノードと End ノードへのアクセスは、通常却下できます。
- フィードバック ループは、表内の "R → W" (または "R+W → W") モードのチャネル アクセスで見つけることができます。この解析は、チャネルのタイプによって補完すると、正しいフィードバック チャネルと不正なフィードバック チャネルを区別できます。
- アウトライン以外のプロセスは、プロセス コードから識別できます。ユーザーは、最上位のデータフロー領域で、プロセスごとに 1 つの関数呼び出しを実行することを目標とし、この呼び出しでは、可能な限り、変数または定数を引数として使用するようにしてください。
これらの問題はコード内で直接修正でき、C シミュレーションを新たに実行すると、更新されたメトリクスと構造でグラフが更新されます。
- パフォーマンスの向上
-
データフロー領域のパフォーマンスで重要な要素のひとつは、その領域を構成するプロセスの TI です。コード アナライザーを使用すると、HLS 合成なしでデータフロー プロセスのパフォーマンスを効率的に改善できます。
ツールバー メニューの Heat Map の選択肢から Performance Guidance を選択すると、グラフ ノードに表示される問題バッジを使用して、パフォーマンスに問題があるプロセスを特定できます。プロセス コードを展開すると、プロセスで見つかった特定の問題の詳細が示されます。これらの問題を調べて、実現可能性、これらの問題の場所、最終的なパフォーマンス目的に応じて、対処するかどうかを決めてください。たとえば、ある特定のプロセスの内部ループで II=1 にする場合、その特定のループのネストで提示されるすべての問題を修正するには、コードを書き直す必要があります。
関連するユース ケースとして、目的が学ぶことであっても検証することであっても、特定のプロセスで TI がどのように計算されたかを理解する必要があることがあります。関数呼び出しとループの横にある TI と II のアノテーションは、この目的のためにプロセスのソース コードをインライン展開して確認できます。
- スループット解析
-
コード アナライザーは、チャネルのスループットの見積もりを表示します。解析を補完し、デザイン パフォーマンスをより理解するため、チャネル幅とその量 (領域の実行あたりの総アクセス) にアクセスすることもできます。ただし、できるだけデザインを合成してスループットの見積もりを検証する必要があります。これは、コード アナライザーが、ほかの合成後やインプリメンテーション後のメトリクスよりも精度の低い合成前の見積もりを使用するからです。