DSP

dsp 优化心得

2019-07-13 14:51发布

1.多重if else 嵌套需要用函数指针来优化! 2.ldbu  .D   *A_s++[A_lx],A_sreg1 //是先取A_s的值,然后在加偏移A_lx 四、        1、源代码: void fir_fxd1(short input[], short coefs[], short out[]) {     int i, j;     for (i = 0; i < 40; i++)     {       for (j = 0; j < 16; j++)             out[i*16+j]= coefs[j] * input[i + 15 - j];    } }        2、改编后的代码: void fir_fxd2(const short input[], const short coefs[], short out[]) {    int i, j;       for (i = 0; i < 40; i++)     {       for (j = 0; j < 16; j++)             out[i*16+j]= coefs[j] * input[i + 15 - j];    }         3、优化方法说明:        C6000编译器如果确定两条指令是不相关的,则安排它们并行执行。 关键字const可以指定一个变量或者一个变量的存储单元保持不变。这有助于帮助编译器确定指令的不相关性。例如上例中,源代码不能并行执行,而结果改编后的代码可以并行执行。        4、技巧:        使用const可以限定目标,确定存在于循环迭代中的存储器的不相关性。 五、        1、源代码: void vecsum(short *sum, short *in1, short *in2, unsigned int N) {     int i;       for (i = 0; i < N; i++)         sum[i] = in1[i] + in2[i]; }        2、改编后的代码: void vecsum6(int *sum, const int *in1, const int *in2, unsigned int N) {     int i;     int sz = N >> 2;       _nassert(N >= 20);       for (i = 0; i < sz; i += 2)     {         sum[i]   = _add2(in1[i]  , in2[i]);         sum[i+1] = _add2(in1[i+1], in2[i+1]);     } }        3、优化方法说明: 源代码中,函数变量的定义是 short *sum, short *in1, short *in2,  改编后的代码函数变量是 int *sum, const int *in1, const int *in2,  整数类型由16位改编成32,这时使用内联指令“_add2”一次可以完成两组16位整数的加法,效率提高一倍。注意这里还使用了关键字const和内联指令_nassert优化源代码。        4、技巧 用内联指令_add2_mpyhl_mpylh完成两组16位数的加法和乘法,效率比单纯16位数的加法和乘法提高一倍。        六、if...else...语句的优化 (一)        1、源代码:     if (sub (ltpg, LTP_GAIN_THR1) <= 0)     {         adapt = 0;                               }     else     {              if (sub (ltpg, LTP_GAIN_THR2) <= 0)         {             adapt = 1;                               }         else         {             adapt = 2;                               }     }        2、改编后的代码:  adapt = (ltpg>LTP_GAIN_THR1) + (ltpg>LTP_GAIN_THR2); (二)        1、源代码:     if (adapt == 0)     {         if (filt>5443)         {             result = 0;         }         else         {             if (filt < 0)             {                 result = 16384;              }             else             {                   filt = _sshl (filt, 18)>>16; // Q15                 result = _ssub (16384, _smpy(24660, filt)>>16);             }         }     }     else     {         result = 0;     }        2、改编后的代码:     filt1 = _sshl (filt, 18)>>16;     tmp = _smpy(24660, filt1)>>16;     result = _ssub(16384, tmp * (filt>=0));     result = result * (!((adapt!=0) (filt>5443)));        (三)        1、源代码: static Word16 saturate(Word32 L_var1) {  Word16 swOut;    if (L_var1 > SW_MAX)  {   swOut = SW_MAX;   giOverflow = 1;  }  else if (L_var1 < SW_MIN)  {   swOut = SW_MIN;   giOverflow = 1;  }  else   swOut = (Word16) L_var1;  /* automatic type conversion */  return (swOut); }        2、改编后的代码: static inline Word32 L_shl(Word32 a,Word16 b)    { return ((Word32)((b) < 0 ? (Word32)(a) >> (-(b)) : _sshl((a),(b)))) ; }        3、优化方法说明:        如果在循环中出现if...else...语句,由于if...else...语句中有跳转指令,而每个跳转指令有5个延迟间隙,因此程序执行时间延长;另外,循环内跳转也使软件流水受到阻塞。直接使用逻辑判断语句可以去除不必要的跳转。例如在例1的源代码最多有两次跳转,而改编后不存在跳转。例和例3同样也去掉了跳转。        4、技巧:        尽可能地用逻辑判断语句替代if...else...语句,减少跳转语句。 七、        1、源程序  dm = 0x7FFF;  for (j = 0; j < nsiz[m]; j = add(j, 1))  {   if (d[j] <= dm)   {    dm = d[j];    jj = j;   }  }  index[m] = jj;        2、优化后的程序  dm0 = dm1 = 0x7fff;          d0  = (Word16 *)&d[0];          d1  = (Word16 *)&d[1];  #pragma MUST_ITERATE(32,256,64);  for (j = 0; j < Nsiz; j+=2)  {   n0 = *d0;   d0 += 2;   n1 = *d1;     d1 += 2;   if (n0 <= dm0)   {    dm0 = n0;    jj0 = j;   }   if (n1 <= dm1)   {    dm1 = n1;    jj1 = j+1;   }  }  if (dm1 != dm0)  {   index[m] = (dm1 < dm0)? jj1:jj0;  }  else  {   index[m] = (jj1 > jj0)? jj1:jj0;  }        3、优化说明         求数组的最小值程序,优化时为了提高程序效率在一个循环之内计算N=1,3,5..n=2,4,6...的最小值,然后在比较二者的大小以求得整个数组的最小值。