打印

C6000点滴学习:c6000系列的C代码优化(四)

[复制链接]
468|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Roses|  楼主 | 2017-11-11 10:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
c6000系列的C代码优化(四)


  四、使用 const可以限定目标优化
        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 = in1 + in2;  
  • }  

复制代码


        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   = _add2(in1  , in2);  
  •         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 的源代码最多有两次跳转,而改编后不存在跳转。例 2 和例 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...的最小值,然后在比较二者的大小以求得整个数组的最小值。  







相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

709

主题

1023

帖子

7

粉丝