カーネル開発のベスト プラクティス - 2023.2 日本語

Vitis 統合ソフトウェア プラットフォームの資料: アプリケーション アクセラレーション開発 (UG1393)

Document ID
UG1393
Release Date
2023-12-13
Version
2023.2 日本語

Alveo アクセラレータ カードとその主要コンポーネント、CPU と Alveo カード間のデータの移動方法に関する基本を確認しました。Vitis アプリケーションを作成するための推奨ガイドラインについても説明しました。このセクションでは、Vitis HLS を使用したコーディングの重要な概念について詳しく説明します。

関数の引数のハードウェア インターフェイスへのマッピング

Vitis HLS ツールは、C/C++ カーネル関数の引数にインターフェイス ポートを自動的に割り当てます。これらの関数引数は、スカラー型またはポインター/配列型のいずれかです。ホストからのパラメーターは、アクセラレータのレジスタに直接書き込まれます。バッファーはグローバル メモリで外部に保持され、アクセラレータはこのグローバル メモリから読み出しと書き込みをします。

スカラー型関数の引数はパラメーターに使用され、ポインター型または配列型の引数はグローバル メモリへのアクセスに使用されます。Vitis HLS は、これらのインターフェイス ポートを AXI プロトコルとしてインプリメントします。このインターフェイス プロトコルの詳細は、「AXI の概要」を参照してください。

ロード/計算/ストア

アルゴリズムは、次に示すように、通信チャネルを使用して load-compute-store の構造にする必要があります。

図 1. ロード/計算/ストア パターン
  • load 関数は、デバイス メモリからカーネルにデータを移動する役割を果たします。この関数はデータ処理は実行しませんが、必要に応じて、バッファリングおよびキャッシングなどの効率的なデータ転送を実行します。
  • compute (計算) 関数は、その名前のとおり、すべてのデータ処理を実行します。開発フローのこの段階では、計算関数の内部構造は重要ではありません。
  • store 関数は load 関数の逆で、compute 関数から結果を取り出してそのデータをカーネル外に移動し、グローバル メモリに転送します。

開発者は、グローバル メモリ アクセスのオーバーヘッドを最小限に抑えるためにメモリ アクセスをコーディングする必要があります。つまり、バーストが推論できるように、連続したアクセスの使用を最大にします。バースト アクセスは、メモリ アクセス レイテンシを隠して、メモリ帯域幅を改善します。

また、グローバル メモリとカーネルの間の最大データ幅は 512 ビットです。データ転送レートを最大にするには、この最大データ幅を使用することをお勧めします。Vitis カーネル フローでは、バースト アクセスを向上するため、Vitis HLS ツールによりデフォルトでカーネル インターフェイスのサイズが 512 ビットに変更されます。

パフォーマンス目標を達成するロード/計算/ストア構造を作成するには、まずカーネル内のデータの流れを設計します。この際、次の点に注意してください。

  • カーネル外からカーネル内にどのようにデータが流れるか。
  • このデータを処理するためにカーネルをどれくらいの速さにする必要があるか。
  • 処理されたデータをカーネル外にどのように書き出すか。

load-compute と compute-store はストリーミング チャネルを介して通信します。ストリーミングとは、データ サンプルが最初のサンプルから順に送信されるデータ転送のことで、アドレス管理を必要とせず、FIFO を使用してインプリメントできます。compute 関数に十分なデータが使用可能になると、計算を開始できます。同様に、データが store 関数で使用可能になると、AXI4 マスター インターフェイスを介してデータを DDR に送信できます。

例 - FIFO を使用したデータフロー

タスク レベルの並列処理

開発者は、アルゴリズムを評価し、タスクレベルの並列処理を実現する方法を決定する必要があります。このタイプの並列処理は、2 次元でイネーブルにできます。

  1. タスクは、互いにオーバーラップさせて実行できます。つまり、計算関数は使用可能なデータがあるかどうかに基づいて開始でき、前の関数を最初に終了する必要はありません。データフローをイネーブルにすると、このタイプの並列処理が推論されます。
  2. タスクは、「トランザクション間隔」と呼ばれる特定の時間内で自動的に再起動できます。つまり、前回の呼び出しが完全に終了する前に、同じ計算関数の次の呼び出しを再開できます。Vitis ツールは、任意のループのパフォーマンス ターゲットにコンパイラ指示子を指定します。この指示子が追加されると、コンパイラは、配列のパーティション、入れ子のループの展開、「ターゲット間隔」の目標を達成するためのループのパイプライン処理など、自動的に必要な変換または変換の組み合わせを実行します。
関数とループのパイプライン処理、ループ展開、および配列のパーティションの詳細は、 『Vitis 高位合成ユーザー ガイド』 (UG1399) を参照してください。

カーネルの論理的な正確さを検証

Vitis HLS デザイン フローを使用する場合、論理的に正しくない C コードを合成して、インプリメンテーションの詳細を解析し、関数が予測どおりに実行されない原因とつきとめるのは時間の無駄です。そのため、高位合成の最初の手順は、適切に記述されたテストベンチを使用して C シミュレーションを実行し、RTL コードを生成する前に C 関数が正しいことを検証することです。適切なテストベンチを記述すると、C 関数を RTL シミュレーションよりも短時間で実行できるので、生産性が上がります。C を使用してアルゴリズムを開発して合成前に検証する方が、RTL コードを開発してデバッグするよりもはるかに高速です。同じ C ベースのテストベンチを使用して C/RTL 協調シミュレーションを実行し、生成された RTL デザインを自動的に検証できます。

これついては、次を含め、 『Vitis 高位合成ユーザー ガイド』 (UG1399) を確認してください。
  • テストベンチの記述
  • C シミュレーションを使用したコードの検証
  • C/RTL 協調シミュレーション
  • Vitis HLS の解析および最適化チュートリアルでは、Vitis HLS ツールの GUI を使用してハードウェア カーネルをビルド、解析、最適化します。
  • アプリケーションのインターフェイスを設計する際のベスト プラクティスは、M_AXI インターフェイスを使用したデザインのベスト プラクティスのチェックリストを参照してください。