AI エンジンには、スカラー算術演算、非線形関数、およびその他の汎用演算のインプリメントに使用できるスカラー プロセッサが含まれています。場合によっては、コードのゴールデン スカラー参照バージョンを用意しておくと便利です。ただし、コードのスカラー バージョンは、ベクター バージョンと比較すると、シミュレーションとハードウェアでの実行にかなり時間がかかることに注意してください。
次に、32 タップ フィルターのスカラー バージョンのコード例を示します。
static cint16 eq_coef[32]={{1,2},{3,4},...};
//keep margin data between different invocations of the graph
static cint16 delay_line[32];
__attribute__((noinline)) void fir_32tap_scalar(input_stream<cint16> * sig_in,
output_stream<cint16> * sig_out){
//For profiling only
unsigned cycle_num[2];
aie::tile tile=aie::tile::current();
for(int i=0;i<SAMPLES;i++){
cycle_num[0]=tile.cycles();//cycle counter of the AI Engine tile
cint64 sum={0,0};//larger data to mimic accumulator
for(int j=0;j<32;j++){
//auto integer promotion to prevent overflow
sum.real+=delay_line[j].real*eq_coef[j].real-delay_line[j].imag*eq_coef[j].imag;
sum.imag+=delay_line[j].real*eq_coef[j].imag+delay_line[j].imag*eq_coef[j].real;
}
sum=sum>>SHIFT;
//produce one sample per loop iteration
writeincr(sig_out,{(int16)sum.real,(int16)sum.imag});
for(int j=0;j<32;j++){
if(j==31){
delay_line[j]=readincr(sig_in);
}else{
delay_line[j]=delay_line[j+1];
}
}
//For profiling only
cycle_num[1]=tile.cycles();//cycle counter of the AI Engine tile
printf("start=%d,end=%d,total=%d\n",cycle_num[0],cycle_num[1],cycle_num[1]-cycle_num[0]);
}
}
void fir_32tap_scalar_init()
{
//initialize data
for (int i=0;i<32;i++){
int tmp=get_ss(0);
delay_line[i]=*(cint16*)&tmp;
}
};
注記:
- 関数
fir_32tap_scalar_init
はカーネルの初期化関数として使用され、graph.run()
の後に一度だけ呼び出されます。 - スカラー プロセッサでは、丸めモードおよび飽和モードはサポートされません。これらは、
shift
などの標準 C 演算を使用してインプリメントできます。 - タイル カウンターは、コードのメイン ループをプロファイリングするのに使用されます。
プロファイリング結果から、各サンプルに 3068 サイクルかかることがわかります。また、AI エンジンのシミュレーションで
--profile
オプションをイネーブルにすると、Vitis IDE の [Profile] セクションに同様の情報を表示させることもできます。図 1. プロファイルの詳細
グラフの構築およびさまざまなプロファイリング手法の詳細は、 『AI エンジン ツールおよびフロー ユーザー ガイド』 (UG1076) の AI エンジンのシミュレーションに基づくパフォーマンス解析とハードウェアでの AI エンジン グラフ アプリケーションのパフォーマンス解析を参照してください。