内核代码剖析 - 2023.2 简体中文

AI 引擎内核与计算图编程指南 (UG1079)

Document ID
UG1079
Release Date
2023-12-04
Version
2023.2 简体中文
每个 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]);