ホストおよびカーネル間でのデータ転送 - 2022.1 日本語

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

Document ID
UG1393
Release Date
2022-05-25
Version
2022.1 日本語

XRT 管理のカーネルおよびカーネル引数の設定の際、アクセラレータ カードまたはデバイスのメモリとの間でデータを転送する場合は、作成されたバッファー オブジェクト (xrt::bo) が使用されます。

通常クラス コンストラクターは、標準の 4K アライメントされたバッファー オブジェクトを割り当てます。次のコードでは、ヒープ メモリ内のユーザー空間によって割り当てられたホスト バッキング ポインターを持つ標準バッファー オブジェクトと、カーネル引数 (krnl.group_id) に関連付けられたメモリ バンクに割り当てられたデバイス側のバッファーを作成します。xrt::bo コンストラクター内のオプションのフラグを使用すると、「特殊なバッファーの作成」に示すような特殊な状況で使用する非標準型のバッファーを作成できます。

std::cout << "Allocate Buffer in Global Memory\n";
auto bo0 = xrt::bo(device, vector_size_bytes, krnl.group_id(0));
auto bo1 = xrt::bo(device, vector_size_bytes, krnl.group_id(1));
auto bo_out = xrt::bo(device, vector_size_bytes, krnl.group_id(2));
重要: 現時点では、ホストからグローバル メモリまでのスループットを最大化するために 4 GB を上回るバッファーは使用できませんが、ザイリンクス ではバッファー サイズをできれば少なくとも 2 MB に抑えることをお勧めしています。

バッファーが確立され、データがいっぱいになった状態で、ホストとカーネル間の転送を有効にするには、次のようないくつかの方法があります。

xrt::bo::sync() の使用
ホストからデバイスに XCL_BO_SYNC_TO_DEVICE フラグ付きでデータを同期する場合は xrt::bo::sync を、デバイスからホストに XCL_BO_SYNC_FROM_DEVICE フラグ付きでデータを同期する場合は xrt::bo::write を、ホスト アプリケーションからバッファーを書き込んだり、デバイスからバッファーを読み出す場合は xrt::bo::read を使用します。
bo0.write(buff_data);
bo0.sync(XCL_BO_SYNC_BO_TO_DEVICE);
bo1.write(buff_data);
bo1.sync(XCL_BO_SYNC_BO_TO_DEVICE);
...
bo_out.sync(XCL_BO_SYNC_BO_FROM_DEVICE);
bo_out.read(buff_data);
注記: ユーザー ポインターからのバッファーの作成に示すように、バッファーがユーザー ポインターを使用して作成される場合、xrt::bo::sync 呼び出しで十分なので、xrt::bo::write または xrt::bo::read コマンドは必要ありません。
xrt::bo::map() の使用
このメソッドは、ホスト側のバッファー バッキング ポインターをユーザー ポインターにマップできるようにします。
// Map the contents of the buffer object into host memory
auto bo0_map = bo0.map<int*>();
auto bo1_map = bo1.map<int*>();
auto bo_out_map = bo_out.map<int*>();

ホスト コードは、データを読み出しおよび書き込み用のユーザー ポインターを連続して実行できます。ただし、マップされたポインターに書き込んだ後 (またはマップされたポインターから読み出す前)、DMA 動作に必要な方向フラグを指定して xrt::bo::sync() コマンドを使用する必要があります。

for (int i = 0; i < DATA_SIZE; ++i) {
   bo0_map[i] = i;
   bo1_map[i] = i;
}

// Synchronize buffer content with device side
bo0.sync(XCL_BO_SYNC_BO_TO_DEVICE);
bo1.sync(XCL_BO_SYNC_BO_TO_DEVICE);

その他のバッファーで説明されるように、XRT ネイティブ API では、その他にもサポートされるバッファー タイプと転送シナリオがあります。