このセクションでは、最初に Vitis アプリケーション開発フローについて学習し、次に FPGA ベースのアクセラレーション用に CPU アプリケーションを再構築する方法を確認し、全体的なパフォーマンス目標を満たすように各カーネルのコードを書き直します。次は、Vitis アプリケーション開発フローのイメージです。
- G++ を使用してアプリケーションをコンパイル
-
C/C++ で記述され、XRT ネイティブ API を使用してコンパイルされたホスト プログラムは、g++ コンパイラを使用してコンパイルされ、x86 プロセッサ上で実行するホスト実行可能ファイルを作成します。ホスト プログラムは、FPGA デバイスの PL 領域内のカーネルと対話します。
- Vitis HLS を使用してカーネルをコンパイル
-
Vitis HLS は、C/C++ ソース コードを入力として受け取り、AMD FPGA 製品用に最適化された RTL デザインに合成するコンパイラです。ザイリンクス オブジェクト (.xo) ファイルを生成するには、各 C++ カーネルを Vitis HLS を使用して合成する必要があります。Vitis リンカーを使用すると、1 つまたは複数の .xo ファイルをリンクのためにペアにし、.xclbin ファイルを生成できます。
Vitis HLS でのカーネル開発の手順は、次のとおりです。
- 関数の C/C++ コードを記述
- C シミュレーションを使用してコードを検証
- C 合成を使用してカーネルを構築
- C++ 出力で生成されたカーネルを検証
- HLS 合成レポートと協調シミュレーション レポートを確認して、パフォーマンスを解析
- パフォーマンス目標が達成されるまで、前の手順を繰り返します。
- Vitis ツールを使用して PL カーネルをリンク
-
Vitis リンカーでザイリンクス オブジェクト (.xo) ファイルとターゲット ハードウェア プラットフォームとリンクし、デバイス バイナリ ファイル (.xclbin) を作成します。このファイルが読み込まれて、Alveo ターゲット プラットフォーム上で実行されます。
ヒント: この段階では、.xclbin ファイルを生成するために Vivado の配置配線機能が呼び出されます。デバイス バイナリのアーキテクチャを定義するために、コンフィギュレーション ファイルを作成して、デバイス バイナリ内に構築するカーネル (または演算ユニット) のインスタンス数、グローバル メモリまたはその他のカーネルに接続するカーネル数、などのオプションを指定できます。このコンフィギュレーションファイルが Vitis リンカーに渡されて、.xclbin が生成されます。
Vitis コンパイラには、生成される .xclbin ファイルの性質と内容を定義する 3 つの異なるビルド ターゲットがあります。そのうち 2 つは検証およびデバッグの目的で使用されるエミュレーション ターゲットで、C ベースのシミュレーションの場合は「ソフトウェア エミュレーション」、RTL 協調シミュレーションの場合は「ハードウェア エミュレーション」です。もう 1 つは Alveo カード上で実行する最終的なプロジェクト出力を構築するための「ハードウェア ターゲット」です。同じホスト プログラムを使用して、任意の .xclbin ターゲットを実行できます。
ヒント: エミュレーション ターゲットのコンパイルは、実際のハードウェアのコンパイルよりもかなり高速です。エミュレーション実行はシミュレーション環境で実行され、デバッグのための情報が表示されます。実物のアクセラレータ カードは必要ありません。 - アプリケーションの実行
- 最後に、アプリケーションを実行すると、ホスト プログラムが Vitis コンパイラで生成された .xclbin ファイルを読み込みます。ホスト アプリケーションは常に CPU 上で実行されます。x86 上でエミュレーションモードで実行することも、実際のアクセラレータ プラットフォーム上で実行することもできます。
Vitis アクセラレーション アプリケーション開発
この設計手法には、主に 2 つの段階があります。
- アプリケーションを構築し、パフォーマンス目標を定義してカーネルを特定します。どのソフトウェア関数をデバイス カーネルにマップするか、どれくらい並列処理が必要か、どのように転送するかなど、アプリケーション アーキテクチャに関する重要事項を決定します。
- 設定された目標を達成する C/C++ カーネルを開発します。開発者はカーネルをインプリメントします。このタスクでは、主にパフォーマンス目標を達成できるようにソース コードを構築し、必要なコンパイラ プラグマを指定します。デザインを確認原則にをソフトウェア プログラマでは、ソフトウェア開発者を対象として、C/C++ で記述されたソフトウェア アルゴリズムからアクセラレーションされたハードウェアを合成するプロセスについて説明したソフトウェア プログラマの設計基本原則を確認してください。
- Valgrind、callgrind、および gprof を使用して C++ アプリケーションをプロファイルし、解析のためのベースラインを作成します。実行時間が最も長い関数は、FPGA でのアクセラレーションの良い候補となります。
- 達成可能な最大スループットは PCIe のパフォーマンスによって制限されます。PCIe のパフォーマンスは、マザーボード、ドライバー、ターゲット プラットフォーム、転送サイズなどのさまざまな要因の影響を受けます。
xbutil dma
テストのような DMA テストを前もって実行し、PCIe 転送の効率的なスループットを計測すると、アクセラレーションの上限を特定できます。 - アルゴリズムを確認し、並列パスを解析して、パフォーマンスのボトルネックを特定します。1 つのパスをアクセラレーションしても、アプリケーション全体では想定したようなアクセラレーションが達成できないことがあります。アクセラレーションの候補を探す場合は、個別の関数のパフォーマンスだけでなく、アプリケーション全体のパフォーマンスを考慮してください。
- 全体的なアクセラレーションの可能性を特定し、アプリケーションのパフォーマンス目標を設定します。
- アクセラレーションする関数を特定し、全体的なアクセラレーションの目標を設定したら、次にその目標を達成するにはどのレベルの並列処理が必要なのかを判断します。
- ホストとデバイス間のデータ転送および FPGA 上での計算の並列処理をイネーブルして、アイドル時間を最小限に抑えます。デバイス カーネルをアクティブな状態に保ち、新しい計算をできるだけ早く頻繁に実行させる。デバイスとのデータ転送を最適化する。
このトピックの詳細は、Vitis ソフトウェア プラットフォームでのデータセンター アプリケーションのアクセラレーション または 『Vitis 高位合成ユーザー ガイド』 (UG1399) の「ソフトウェア プログラマのための設計原則」を参照してください。
C/C++ カーネルの開発手法
ソフトウェア プログラムを自動的にハードウェアに変換 (または合成) して許容可能な QoR (結果の品質) を達成できるようになっても、Vitis HLS ツールがパフォーマンス目標を達成できるようにソフトウェアを書き直すなどの追加作業が必要です。このためには、FPGA デバイス上で実行するのに適切なソフトウェアを記述するベスト プラクティスを理解する必要があります。次のいくつかのセクションでは、プログラムを構成するマクロレベルのアーキテクチャ最適化を最初に特定し、パフォーマンス目標を高める詳細なマイクロレベルのアーキテクチャ最適化に焦点を当てる方法について説明します。最適なアプリケーション パフォーマンスに必要な次のカーネル要件は、アーキテクチャの定義段階で既に特定されているはずです。
- スループット目標
- レイテンシ目標
- データパス幅
- アクセラレーションされたカーネルの数
- インターフェイスの帯域幅
これらの要件により、カーネル開発および最適化プロセスが決まります。全体的なアプリケーション パフォーマンスは、各カーネルが指定したスループットを満たすことにより予測されるので、カーネルのスループット目標を達成することが主な目的となります。
このため、カーネル開発手法はスループット ドリブン方法に従って、アウトサイドインで開発していきます。この手法には、次の 2 つの段階が含まれます。
- カーネルのマクロ アーキテクチャを定義してインプリメント
- カーネルのマイクロ アーキテクチャをコード記述して最適化
要件、注意事項、およびより高いパフォーマンスを達成するためのコードの再構築方法の詳細は、C/C++ カーネルの開発手法 を参照してください。