グラフのスループットのプロファイリング - 2023.2 日本語

AI エンジン ツールおよびフロー ユーザー ガイド (UG1076)

Document ID
UG1076
Release Date
2023-12-04
Version
2023.2 日本語

グラフのスループットは、毎秒生成 (または消費) されるバイト数の平均です。event::io_stream_start_to_bytes_transferred_cycles 列挙を使用して、特定の量のデータを転送するのにかかるサイクル数を記録できます。

event::start_profiling() の後、2 つのパフォーマンス カウンター performance counter 0performance counter 1 が連動します。performance counter 0 が最初のデータを受信すると、カウンターをインクリメントし始めます。performance counter 1 はデータを受信するとインクリメントします。performance counter 1event::start_profiling で指定されたデータ量に等しくなると、performance counter 0 に停止を通知するイベントが生成されます。event::read_profiling() でリードバックされた値が performance counter 0 の値です。performance counter 0 が停止した後、カウンターの値はデータの転送にかかったサイクル数を表します。

event::start_profiling で指定されたデータ量が転送されていない場合、performance counter 0 は停止しません。指定されたデータ量が転送された後、performance counter 0 は停止します。この手法は、既知のデータ量の転送にかかる時間をプロファイリングする場合に有効です。ただし、追加のデータが転送された場合、performance counter 0 がカウントを継続します。
警告: グラフのスループットをプロファイルする方法では、反復回数が少なすぎる場合、グラフのレイテンシまたはグラフおよびカーネル API 呼び出しのオーバーヘッドが無視できる量でない場合があります。このようなオーバーヘッドの影響を最小限に抑えるために、反復回数を多くすることを推奨します。

グラフ出力を使用したグラフ スループットのプロファイル

次に、グラフ出力を使用してグラフのスループットをプロファイリングする例を示します。
auto s2mm_run = s2mm(out_bo, nullptr, OUTPUT_SIZE);
const int WINDOW_SIZE_in_bytes=8192;
int iterations=999;
//Third parameter is the amount of data to be transferred (in bytes).
event::handle handle = event::start_profiling(gr_pl.dataout, event::io_stream_start_to_bytes_transferred_cycles, WINDOW_SIZE_in_bytes*iterations);
if(handle==event::invalid_handle){
    printf("ERROR:Invalid handle. Only two performance counter in a AIE-PL interface tile\n");
    return 1;
} 
gr_pl.run(iterations);
s2mm_run.wait();//performance counter 0 stops, assumming s2mm able to receive all data 
long long cycle_count = event::read_profiling(handle);
double throughput = (double)WINDOW_SIZE_in_bytes*iterations / (cycle_count * 1e-9); //bytes per second
event::stop_profiling(handle);//Performance counter is released and cleared

上記のコードでは、すべてのデータが PLIO を介して転送されるように、実行は s2mm が完了するまで待機します。

AI エンジン シミュレーション フローで API を使用する場合は、代わりに graph.wait() を使用できます。graph.wait() の後、ウィンドウ バッファーから PLIO にデータを転送するために、API で追加のサイクルが必要です。これを解決するには、オーバーヘッドが十分小さくなるように反復回数を多くするのが 1 つの方法です。別の解決策として、PLIO を介してすべてのデータが転送されるのに十分な時間となるサイクル数だけ graph.wait(<NUM_CYCLES>) を使用する方法もあります。

グラフ入力を使用したグラフ スループットのプロファイル

PLIO からカーネルへのストリームと入力バッファーの DMA は、コンフィギュレーション直後にデータを受信できるようになります。PL カーネル mm2s がアサートされると、graph::run の前でも入力ネットでデータを受信できます。PLIO 入力をプロファイリングするには、event::start_profiling() 後に PL をアサートするのが 1 つの方法です。次に、グラフ入力を使用してグラフのスループットをプロファイリングする例を示します。
const int WINDOW_SIZE_in_bytes=8192;
int iterations=999;
//Third parameter is the amount of data to be transferred (in bytes).
event::handle handle = event::start_profiling(gr_pl.in, event::io_stream_start_to_bytes_transferred_cycles, WINDOW_SIZE_in_bytes*iterations);
if(handle==event::invalid_handle){
    printf("ERROR:Invalid handle. Only two performance counter in a AIE-PL interface tile\n");
    return 1;
} 
gr_pl.run(iterations);
auto mm2s_run = mm2s(nullptr, OUTPUT_SIZE_MM2S);//After start profiling, send data from mm2s
gr_pl.wait();//performance counter 0 stops, assumming s2mm able to receive all data 
long long cycle_count = event::read_profiling(handle);
double throughput = (double)WINDOW_SIZE_in_bytes*iterations / (cycle_count * 1e-9); //bytes per second
event::stop_profiling(handle);//Performance counter is released and cleared
データ転送量が不明な場合、この方法でグラフ スループットを見積もることもできます。たとえば、PL カーネルがフリーランニングで、グラフ出力 AI エンジン/PL インターフェイス列でパフォーマンス カウンターが最大値に達した場合でも、グラフ入力を介してグラフのスループットをプロファイルできます。
const int WINDOW_SIZE_in_bytes=8192;
int iterations=999;
//Third parameter is the amount of data to be transferred (in bytes).
event::handle handle = event::start_profiling(gr_pl.in, event::io_stream_start_to_bytes_transferred_cycles, WINDOW_SIZE_in_bytes*iterations);
if(handle==event::invalid_handle){
    printf("ERROR:Invalid handle. Only two performance counter in a AIE-PL interface tile\n");
    return 1;
} 
gr_pl.run(iterations);
gr_pl.wait();//performance counter 0 does not stop
//Read performance counter value immediately
//Assuming that overhead can be negligible if iteration is large enough
long long cycle_count = event::read_profiling(handle);
double throughput = (double)WINDOW_SIZE_in_bytes*iterations / (cycle_count * 1e-9); //bytes per second
event::stop_profiling(handle);//Performance counter is released and cleared