各 AI エンジンには 64 ビット カウンターが 1 つ含まれています。AI エンジン API クラス
aie::tile
には、このカウンター値を読み出す cycles()
メソッドがあります。次に例を示します。aie::tile tile=aie::tile::current(); //get the tile of the kernel
unsigned long long time=tile.cycles();//cycle counter of the tile counter
カウンターは、継続的に実行されます。カウンターは、何回でも読み出すことができます。カーネルが読み出した値は、メモリに書き込むか、さらなる解析用にストリーム出力できます。たとえば、次のコードのレイテンシをプロファイルするには、コードをプロファイルする前にカウンター値を読み出し、コードを実行した後に再度読み出します。
aie::tile tile=aie::tile::current();
unsigned long long time1=tile.cycles(); //first time
for(...){...}
unsigned long long time2=tile.cycles(); //second time
long long time=time2-time1;
writeincr(out,time);
その後、ホスト アプリケーションで 2 つ目の値から 1 つ目の値を引いて、カーネルのループのレイテンシを調べることができます。
カーネルの異なる実行間、またはループの異なる反復間で読み出したデータを比較することにより、データを使用してレイテンシを計算できます。たとえば次のコードは、非同期バッファーでの特定の演算のレイテンシを取得します。
aie::tile tile=aie::tile::current();
for(...){//outer loop
unsigned long long time=tile.cycles(); //read counter value
writeincr(out,time);
win_in.acquire();
for(...){...} //inner loop
win_in.release();
}
非同期バッファーの取得と解放のレイテンシと内側ループの実行時間は、2 つ目の値から 1 つ目の値を引いて計算できます。
カウンター値は、データ メモリにも書き込むことができます。この値は、シミュレーションで
printf
を使用して読み出すか、ハードウェアのホスト コードで読み出します。書き込まれた値がほかのコードで使用されない場合、volatile
修飾子を使用して、カウンターの値の保存を強制できます。この修飾子は、コンパイラの最適化によりこの変数が削除されないようにします。次に例を示します。static unsigned long long cycle_num[2];
aie::tile tile=aie::tile::current();
volatile unsigned long long *p_cycle=cycle_num;
*p_cycle=tile.cycles();//cycle_num[0]
for(...){...}
*(p_cycle+1)=tile.cycles();//cycle_num[1]
printf("cycles=%lld\n",cycle_num[1]-cycle_num[0]);