电子产业
数字化服务平台

扫码下载
手机洽洽

  • 微信小程序

    让找料更便捷

  • APP

    随时找料

    即刻洽谈

    点击下载PC版
  • 公众号

    电子元器件

    采购信息平台

  • 移动端

    生意随身带

    随时随地找货

  • 华强商城公众号

    一站式电子元器件

    采购平台

  • 芯八哥公众号

    半导体行业观察第一站

C6000软件优化经验总结(2)

来源:-- 作者:-- 浏览:537

标签:

摘要:四、 1、源代码: void fir_fxd1(short input[], short coefs[], short out[]) { int i, j; for (i = 0; i < 40; i++)

四、

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 coef

s[], 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(Word32a,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...的最小值,然后在比较二者的大小以求得整个数组的最小值。

型号 厂商 价格
EPCOS 爱普科斯 /
STM32F103RCT6 ST ¥461.23
STM32F103C8T6 ST ¥84
STM32F103VET6 ST ¥426.57
STM32F103RET6 ST ¥780.82
STM8S003F3P6 ST ¥10.62
STM32F103VCT6 ST ¥275.84
STM32F103CBT6 ST ¥130.66
STM32F030C8T6 ST ¥18.11
N76E003AT20 NUVOTON ¥9.67
Baidu
map