每个 AI 引擎都有一个 64 位计数器。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);
随后即可在主机应用中检验内核中循环的时延,只需将第二次的值减去第一次的值即可。
通过比较不同内核执行之间或者不同循环迭代之间读回的数据,即可使用此数据来计算时延。例如,以下代码尝试获取异步缓冲器上某些操作的时延:
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();
}
随后即可计算异步缓冲器获取和释放的时延加上内层循环执行时间,只需将第二次的值减去第一次的值即可。
计数器值也可写入数据存储器。该值可供
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]);