c6000系列的C代码优化总结

2019-08-06 16:48发布

C6X_Optimizing_summarization.pdf (331.96 KB, 下载次数: 182) 2012-12-11 14:40 上传 点击文件名下载附件

c6000系列的C代码优化总结
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
15条回答
五谷道场
2019-08-06 23:43
四、使用 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...的最小值,然后在比较二者的大小以求得整个数组的最小值。  
八、 循环内部存在 if判断程序的优化
1、源程序  
        for (k = 0; k < NB_PULSE; k++)   
    {  
        i = codvec[k];  
        j = sign;  
        index = mult(i, Q15_1_5);  
        track = sub(i, extract_l(L_shr(L_mult(index, 5), 1)));  
        if (j > 0)  
        {  
            if (i < l_subfr) code = add(code, 4096);
             codvec[k] += (2 * L_SUBFR);  
        }  
        else  
        {  
            if (i < l_subfr) code = sub(code, 4096);  
            index = add(index, 16);  
        }  
        if (indx[track] < 0)  
        {  
            indx[track] = index;  
        }  
        else  
        {  
            if (((index ^ indx[track]) & 16) == 0)  
            {  
                if (sub(indx[track], index) <= 0)  
                {  
                    indx[track] = shl((indx[track] & 16), 3)  
                   + shr(extract_l(L_mult((indx[track]&15), NB_POS)), 1) + (index & 15);  
                }  
                else  
                {   indx[track] = shl((index & 16), 3)  
                   + shr(extract_l(L_mult((index & 15),NB_POS)), 1) + (indx[track] & 15);  
                }  
            }  
            else
            {  
                if (sub((indx[track] & 15), (index & 15)) <= 0)  
                {  
                    indx[track] = shl((index & 16), 3)  
                  + shr(extract_l(L_mult((index & 15),NB_POS)), 1) + (indx[track] & 15)
                }  
                else  
                {   indx[track] = shl((indx[track] & 16), 3)  
                    + shr(extract_l(L_mult((indx[track] & 15),NB_POS)), 1) + (index & 1
                }  
            }  
        }  
    }  
2、优化后的程序  
        for (k = 0; k < 8; k++)   
    {  
        i         = codvec[k];  
        j         = sign;  
        index           = _smpy(i, 6554)>>16;  
        track         = i - index*5;  
        con              = (j > 0);  
                codvec[k]    = codvec[k] + 110*con;  
                           index     = index + (!con)*16;  
        conn      = (i < l_subfr);  
        cono    = (j > 0)? 1:-1;  
        code  = code + 4096*conn*cono;  
                           n0   = index;  
                           t0   = indx[track];  
                           n1   = n0&16;  
                           t1   = t0&16;  
                           n2   = n0&15;  
                           t2   = t0&15;  
        tmp0    = (_sshl(n1,19)>>16) + n2*NB_POS + t2;  
        tmp1    = (_sshl(t1,19)>>16) + t2*NB_POS + n2;  
        conp    = (((n1 == t1)&&(t0 > n0))||((n1 != t1)&&(t2 <= n2)));  
                           tmp   = conp*tmp0 + (!conp)*tmp1;  
        if (t0 < 0)  
            indx[track] = n0;  
        else  
            indx[track] = tmp;  
}  
  3、优化说明  
     源程序中在循环中含有许多的 if 结构,在优化时对 if 结构首先进行化简,再将化简后的 if结构用条件运算表达式进行改写,最后使循环可以 Pipeline。  
九、 少量中值问题的优化
1、源程序  
        for (i = 0; i < n; i++)   
    {  
            max = -32767;  
            for (j = 0; j < n; j++)  
            {  
                    if (sub (tmp2[j], max) >= 0)  
                            {  
                                max = tmp2[j];  
                                ix = j;  
                    }  
                     }  
                     tmp2[ix] = -32768;  
                     tmp = ix;  
        }  

2、优化后的程序  
       if (n0>n1) {temp=n0;n0=n1;n1=temp;}  
       if (n1>n2) {temp=n1;n1=n2;n2=temp;}  
       if (n2>n3) {temp=n2;n2=n3;n3=temp;}  
       if (n3>n4) {temp=n3;n3=n4;n4=temp;}  
       if (n0>n1) {temp=n0;n0=n1;n1=temp;}  
       if (n1>n2) {temp=n1;n1=n2;n2=temp;}  
       if (n2>n3) {temp=n2;n2=n3;n3=temp;}  
       if (n0>n1) {temp=n0;n0=n1;n1=temp;}  
       if (n1>n2) {return n1;}  
3、优化说明  
     源程序也为一个求中值的问题,由于已知循环次数固定为 5,因此将循环展开使用 if语句直接求取中值。  
十、 位操作优化
1、源程序  
static Word16 Bin2int (Word16 no_of_bits,    Word16 *bitstream)   
{  
    Word16 value, i, bit;  
    value = 0;  
        for (i = 0; i < no_of_bits; i++)   
    {  
        value = shl (value, 1);  
        bit = *bitstream++;  
        if (sub (bit, BIT_1) == 0)  
        value = add (value, 1);  
    }  
    return (value);  
}  
        for (i = 0; i < prmno[mode]; i++)   
    {  
        prm = Bin2int (bitno[mode], bits);  
        bits += bitno[mode];  
    }  
2、优化后的程序  
    value = 0;  
    bitsp = bits;  
    bitnop= &bitno[mode][0];  
    j  = *bitnop++;  
    j1 = *bitnop++;  
    j2 = *bitnop++;  
    j3 = *bitnop++;  
    j4 = *bitnop++;  
    _nassert(loop[mode]>=35);  
        for (i = 0; i < loop[mode]; i++)   
    {  
        value = value*2 + *bitsp++;  
        j--;  
        if (j == 0)  
        {  
           *prm++ = value;  
           value = 0;  
           j  = j1;  
           j1 = j2;  
           j2 = j3;  
           j3 = j4;  
           j4 = *bitnop++;  
        }  
    }  
3、优化说明  
源程序按照数据位流定义取出参数,为双重循环结构,优化中采用重新根据位流的 bit
长度定义循环次数,化简为单重循环,然后优化循环,去除 boundary,使 pipeline 的数目最小。

一周热门 更多>