累加器寄存器 - 2022.1 简体中文

AI 引擎内核编码 最佳实践指南 (UG1079)

Document ID
UG1079
Release Date
2022-05-25
Version
2022.1 简体中文

累加寄存器位宽为 384 位,可视作为 8 条矢量通道,每条通道均为 48 位。其构想是获得 32 位乘法结果,并将这些结果加以累加,同时确保不发生位溢出。16 个防护位允许最多 216 次累加。定点矢量 MAC 和 MUL 内部函数的输出存储在累加器寄存器中。下表显示了一组累加器寄存器以及将较小的寄存器组合为大型寄存器的方式。

表 1. 累加器寄存器
384 位 768 位
aml0 bm0
amh0
aml1 bm1
amh1
aml2 bm2
amh2
aml3 bm3
amh3

累加器寄存器以字母“am”作为前缀。其中两个累加器寄存器混叠,形成 768 位寄存器并以“bm”作为前缀。

移位 - 舍入 - 饱和 srs() 内部函数用于将值从累加器寄存器移至含任何必要的移位和舍入的矢量寄存器。

v8int32 res = srs(acc, 8); // shift right 8 bits, from accumulator register to vector register

上移 ups() 内部函数用于将值从矢量寄存器移至含上移的累加器寄存器:

v8acc48 acc = ups(v, 8); //shift left 8 bits, from vector register to accumulator register

set_rnd()set_sat() 内部函数用于设置累加结果的舍入和饱和模式,clr_rnd()clr_sat() 内部函数则用于清除舍入和饱和模式,即,将累加结果截位。

请注意,仅当运算经过移位 - 舍入 - 饱和数据路径时,移位、舍入或饱和模式才会生效。有时,内部函数仅使用矢量前加器运算,其中配置不含移位、舍入或饱和模式。此类运算有加法、减法、绝对值、矢量比较或矢量选择/乱序。您可选择使用 MAC 内部函数来代替使用移位、舍入或饱和模式配置执行减法。以下代码用于在 vavb 之间执行减法,并以 mul 代替 sub 内部函数。

v16cint16 va, vb;
int32 zbuff[8]={1,1,1,1,1,1,1,1};
v8int32 coeff=*(v8int32*)zbuff;
v8acc48 acc = mul8_antisym(va, 0, 0x76543210, vb, 0, false, coeff, 0 , 0x76543210);
v8int32 res = srs(acc,0);

浮点内部函数无需独立的累加寄存器,而改为在矢量寄存器中返回其结果。以下串流数据 API 可用于在级联串流上读写浮点累加器数据。

v8float readincr_v8(input_stream_accfloat * str);
v4cfloat readincr_v4(input_stream_caccfloat * str);
void writeincr_v8(output_stream_accfloat* str, v8float value);
void writeincr_v4(output_stream_caccfloat* str, v4cfloat value);

如需了解有关窗口和串流数据 API 的更多信息,请参阅 Versal ACAP AI 引擎编程环境用户指南(UG1076) 中的窗口和串流数据 API

存储器中的数据大小对齐到下一个 2 的幂值(此处 64b 对应 acc48),因此最好使用 sizeof 来判定元素上的位置。以下代码提供了打印累加器矢量寄存器的示例。

v8acc48 vacc; //cascade value
const int SIZE_ACC48=sizeof(v8acc48)/8;
for(int i=0;i<8;i++){//8 number
  int8 *p=(int8*)&vacc+SIZE_ACC48*i;//point to start of each acc48
  printf("acc value[%d]=0x",i);
  for(int j=5;j>=0;j--){//print each acc48 from higher byte to lower byte
    printf("%02x",*(p+j));
  }
  printf("\n");
}

输出如下所示。

acc value[0]=0x000000000000
acc value[1]=0x000000000001
acc value[2]=0x000000000002
acc value[3]=0x000000000003
acc value[4]=0x000000000004
acc value[5]=0x000000000005
acc value[6]=0x000000000006
acc value[7]=0x000000000007