DSP程序优化总结_第1页
DSP程序优化总结_第2页
DSP程序优化总结_第3页
DSP程序优化总结_第4页
DSP程序优化总结_第5页
已阅读5页,还剩18页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、DSP程序优化方法总结1 .选择适当的算法和数据结构重要的是选择适当的数据结构,如果在随机存储数量中使用了大量插入和删除指令,则链表的使用速度快得多。 数组和指针语句有非常密切的关系,一般来说,指针灵活简洁,数组直观容易理解。 大多数编译器比使用数组生成的代码的指针更短,执行效率更高。在许多情况下,使用指针运算代替数组索引通常会生成快速而短的代码。 通常,指针的代码速度比数组索引快,占用面积小。 使用多维数组,差异会变得明显。 以下代码的作用相同,但效率不同。数组索引指针运算。For (; p=arrayA=arrayt ; for (; 表示)。a=*(p )的双曲馀弦值。 的双曲馀弦值。

2、的双曲馀弦值。 的双曲馀弦值。 的双曲馀弦值。 的双曲馀弦值。 的双曲馀弦值。 的双曲馀弦值。 的双曲馀弦值。 的双曲馀弦值。 的双曲馀弦值。 的双曲馀弦值。 的双曲馀弦值。 的双曲馀弦值。 的双曲馀弦值。指针方法的优点在于,只要在每次加载地址p时对array的地址使p递增就可以。 在数组索引法中,需要对每个循环根据t值求出数组下标的复杂运算。2 .使用尽可能小的数据类型不能用整数变量定义可由字符类型(char )定义的变量。不能用整数变量定义的变量,不要使用长整数。 不要使用浮点型(float )变量,而不要使用浮点型变量。 当然,定义变量后,不要超出变量的范围。 如果代入超出变量范围的值,

3、c编译器不会出现错误,但程序的执行结果是错误的。 另外,这样的错误很难发现。在ICCAVR中,可以将Options配置为使用printf参数,尽可能使用基本类型参数(%c、%d、%x、%x、%u、%s格式指定符),而不使用长整数参数(%ld、%lu、%lx、%lx、%lx格式指定符) 对于浮点型参数(%f ),其他c编译器也是一样的。 如果其他条件不变,则使用%f参数会生成更多的代码,从而降低执行速度。3 .减少运算强度(1)、检查表(游戏程序员必修课)聪明的游戏虾基本上在自己的主周期里什么都不计算。 绝对计算之后,再循环查表。 让我们看看下面的例子。旧代码:长factorial (int I

4、 )举止if (i=0)返回1;else返回I * factorial (I-1 )以下新代码:静态长factorial _ table = 1,1,2,6,24,120,720/* etc */长factorial (int I )举止return factorial_tablei;以下如果表很大,很难写,请写init函数,在循环外暂时生成表。(2),求馀数运算a=a%8;可以更改为:a=a7;说明:位操作在1个指令周期内完成,但大部分c编译器的“%”运算通过调用子程序完成,代码长度、执行速度变慢。 通常,只要求2n角的馀数,就可以用位操作的方法来代替。(3)、平方运算a=pow(a,2.0

5、 )可以更改为:a=a*a;说明:在内置硬件乘法器的单片机(例如51系列)中,乘法运算要比平方运算快得多。 由于通过调用子程序来实现浮点数的平方,因此在内置有硬件乘法器的AVR单片机中,可以如ATMega163中那样,以2个时钟周期完成乘法运算。 即使在没有内置硬件乘法器的AVR单片机中,乘法的子程序也比平方运算的子程序代码短,执行速度快。求三次方时,如下所示a=pow(a,3 )。 0;更改后:a=a*a*a;效率的改善变得显着。(4)基于移位的乘法除法运算a=a*4;b=b/4;可以更改为:a=a2;b=b2;通常,如果需要乘以或除以2n,可以用移位的方法来替换。 在ICCAVR中,乘以2

6、n,生成向左移动的代码,乘以其他整数,或者除以任意数,就可以调用乘法程序。 以移位方式获得的代码比调用乘法程序所生成的代码更有效。 实际上,用整数相乘或除以,可以通过以下偏移方法获得结果:a=a*9可以更改为:a=(a3) a将原来的公式替换为运算量更少的公式,典型的例子:如下所示旧代码:x=w % 8;y=pow(x,2.0 )z=y * 33;for (i=0; i MAX; PS )举止h=14 * i;打印( % d ,h );以下新代码:x=w 7; /*位操作比馀数运算更快*/y=x * x; /*乘法比平方运算快*/z=(y 5) y; 位移乘法比乘法快*/for (i=h=0;

7、 i MAX; PS )举止h =14; /*加法比乘法快*/打印( % d ,h );以下(5),避免不必要的整数除法整数除法是整数运算中最慢的,所以要尽量避免。 整数除法是可以用乘法代替除法的除法。 因为此替换的副作用在计算乘积时可能会溢出,所以只能用一定范围的除法来使用。不好的代码:PS、j、k、m;m=i/j/k;推荐代码:PS、j、k、m;m=i/(j * k )(6),使用递增和递减的运算符在使用加法和减法运算符时,请尽量使用增量和减法运算符。 增量运算符的语句比赋值运算符快。 这是因为大多数CPU不需要在内存字的增量运算和减量运算中显式使用内存的读取指令和写入指令。 例如,以下语

8、句x=x 1;模仿大多数微机汇编语言时,会生成以下代码:移动a、x; 从内存中取出x并存储到累加器a中add A,1; 累加器a 1store x; 把新值恢复为x使用增量操作符时,将生成以下代码incr x; x 1很明显,不取命令和保存命令,执行增减操作的速度变快,同时长度也变短了。(7),使用复合代入式复合赋值表达式(例如a-=1或a=1)可以生成高质量的程序代码。(8),提取共同的子公式在某些情况下,c编译器可能无法从浮点表达式中提取公共子表达式。 这是因为相当于对公式进行排序。 特别是,编译器在提取共同的子式之前不能以代数的等价关系对式进行排序。 在这种情况下,程序员必须手动提交公开

9、的子表达式(VC.NET具有“全局优化”选项,但不知道其效果)。不好的代码:浮点a、b、c、d、e、f;的双曲馀弦值。 的双曲馀弦值。 的双曲馀弦值。e=b * c/d;f=b/d * a;推荐代码:浮点a、b、c、d、e、f;的双曲馀弦值。 的双曲馀弦值。 的双曲馀弦值。const float t(b/d )e=c * t;f=a * t;不好的代码:浮点a、b、c、e、f;的双曲馀弦值。 的双曲馀弦值。 的双曲馀弦值。e=a/c;f=b/c;推荐代码:浮点a、b、c、e、f;的双曲馀弦值。 的双曲馀弦值。 的双曲馀弦值。const float t(1.0f/c )e=a * t;f=b *

10、 t;4 .结构成员的布局许多编译器都有“对齐结构词、双重词和四重词”选项。 但是,需要改进结构成员的对齐,某些编译器分配给结构成员空间的顺序可能与声明不同。 但是,一些编译器不提供这些功能或效果不好。 因此,为了以最小的成本实现最高的结构和结构成员的对准,建议使用以下方法(1)按数据类型的长度排序将结构的成员按该类型的长度排列,声明成员时将长的类型放在短的类型之前。 编译器必须在偶数地址边界中存储长数据类型。 在宣告复杂的数据类型(多字节数据和单字节数据两者)时,通过首先存储多字节数据,然后存储单字节数据,可以避免存储器的空洞。 编译器会自动将结构的实例与内存的偶数边界对齐。(2)将结构体填

11、充为最长型长度的整数倍将结构填充为最长类型长度的整数倍。 这样,当结构的第一个成员对齐时,所有结构都自然地对齐。 此示例说明如何更改结构成员的顺序不好的代码,一般顺序:结构举止char a5;龙k;双倍x; baz;手动输入了建议的代码、新顺序和几个字节结构举止双倍x;龙k;char a5;char pad7; baz;此规则也适用于类成员的布局。(3)按数据类型的长度对局部变量进行排序如果编译器被分配给局部变量空间,则必须按照源代码中声明的顺序,将长变量放在短变量的前面,就像在前面的规则中一样。 如果第一个变量对齐,则其他变量将连续存储,并自然对齐,而不填充字节。 某些编译器无法生成4字节对

12、齐的堆栈,因为在分配变量时,变量的顺序不会自动更改,所以可能无法对齐4字节。 以下示例显示了局部变量声明的排序不好的代码,普通的顺序短ga、gu、gi;龙福o,bar;双x,y,z3;char a、b;浮动棒;建议的代码,改进的顺序双倍z 3;双倍x,y;龙福o,bar;浮动棒;短ga、gu、gi;(4)将频繁使用的指针型参数复制到局部变量中。不要在函数中频繁使用指针类型参数指定的值。 因为编译器不知道指针之间是否存在冲突,所以指针类型参数通常不会被编译器优化。 这种数据不能存储在寄存器中,显着占用了存储器带宽。 很多编译器具有“假设不发生冲突”优化开关(需要在VC中手动添加编译器的命令行/O

13、a或/Ow )。 请注意,这使编译器可以假设两个不同的指针始终具有不同的内容,而无需将指针类型参数保存到局部变量中。 否则,请将指针指向的数据保存到本地变量中。 如果需要,在函数结束前复制回去。不好的代码:/假设q =rvoid I sqrt (无符号长龙a,无符号长龙* q,无符号长龙* r )举止*q=a;if (a 0)举止while (*q (*r=a/*q ) )举止*q=(*q *r) 1;以下以下*r=a - *q * *q;以下推荐代码:/假设q =rvoid I sqrt (无符号长龙a,无符号长龙* q,无符号长龙* r )举止无符号长QQ,rr;qq=a;if (a 0)举止while (qq (rr=a/qq ) )举止qq=(qq rr) 1;以下以下rr=a - qq * qq;*q=qq;*r=rr;以下5 .循环优化(1),充分分解小循环为了充分利用CPU

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论