1、选择合适算法和数据结构
应该熟悉算法语言知道各种算法优缺点具体资料请参见相应参考资料有
很多计算机书籍上都有介绍将比较慢顺序查找法用较快二分查找或乱序查找
法代替插入排序或冒泡排序法用快速排序、合并排序或根排序代替都可以大大
提高执行效率.选择种合适数据结构也很重要比如你在堆随机存
放数中使用了大量插入和删除指令那使用链表要快得多
与指针语句具有十分密码关系般来说指针比较灵活简洁而则比
较直观容易理解对于大部分编译器使用指针比使用生成代码更短
执行效率更高但是在Keil中则相反使用比使用指针生成代码更短
3、使用尽量小数据类型
能够使用型(char)定义变量就不要使用整型()变量来定义;能够使用
整型变量定义变量就不要用长整型(long )能不使用浮点型(float)变量就
不要使用浮点型变量当然在定义变量后不要超过变量作用范围如果超过变
量范围赋值C编译器并不报错但运行结果却错了而且这样很难
发现
在ICCAVR中可以在Options中设定使用prf参数尽量使用基本型参数(%c、
%d、%x、%X、%u和%s格式说明符)少用长整型参数(%ld、%lu、%lx和%lX格式说明
符)至于浮点型参数(%f)则尽量不要使用其它C编译器也样在其它条件不
变情况下使用%f参数会使生成代码数量增加很多执行速度降低
4、使用自加、自减指令
通常使用自加、自减指令和复合赋值表达式(如a-=1及a1等)都能够生成高质量
代码编译器通常都能够生成inc和dec之类指令而使用a=a+1或a=a-1之类
指令有很多C编译器都会生成二到三个字节指令在AVR单片适用ICCAVR、
GCCAVR、IAR等C编译器以上几种书写方式生成代码是样也能够生成高质量
inc和dec之类代码
5、减少运算强度
可以使用运算量小但功能相同表达式替换原来复杂表达式如下:
(1)、求余运算
a=a%8;
可以改为:
a=a&7;
说明:位操作只需个指令周期即可完成而大部分C编译器“%”运算均是调
用子来完成代码长、执行速度慢通常只要求是求2n方余数均可使用
位操作方法来代替
(2)、平方运算
a=pow(a,2.0);
可以改为:
a=a*a;
说明:在有内置硬件乘法器单片机中(如51系列)乘法运算比求平方运算快得多
浮点数求平方是通过子来实现在自带硬件乘法器AVR单片
机中如ATMega163中乘法运算只需2个时钟周期就可以完成既使是在没有内置
硬件乘法器AVR单片机中乘法运算子比平方运算子代码短执行
速度快
如果是求3次方如:
a=pow(a,3.0);
更改为:
a=a*a*a;
则效率改善更明显
(3)、用移位实现乘除法运算
a=a*4;
b=b/4;
可以改为:
a=a<<2;
b=b>>2;
说明:通常如果需要乘以或除以2n都可以用移位方法代替在ICCAVR中如果
乘以2n都可以生成左移代码而乘以其它整数或除以任何数均乘除法
子用移位方法得到代码比乘除法子生成代码效率高实际上
只要是乘以或除以个整数均可以用移位方法得到结果如:
a=a*9
可以改为:
a=(a<<3)+a
6、循环
(1)、循环语
对于些不需要循环变量参加运算任务可以把它们放到循环外面这里任务包
括表达式、、指针运算、访问等应该将没有必要执行多次操作
全部集合在起放到个init化中进行
(2)、延时:
通常使用延时均采用自加形式:
void delay (void)
{
unsigned i;
for (i=0;i<1000;i)
}
将其改为自减延时:
void delay (void)
{
unsigned i;
for (i=1000;i>0;i--)
}
两个延时效果相似但几乎所有C编译对后种生成代码均比前
种代码少1~3个字节几乎所有MCU均有为0转移指令采用后种方式能
够生成这类指令
在使用while循环时也样使用自减指令控制循环会比使用自加指令控制循环生
成代码更少1~3个字母
但是在循环中有通过循环变量“i”读写指令时使用预减循环时有可能使
超界要引起注意
(3)while循环和do…while循环
用while循环时有以下两种循环形式:
unsigned i;
i=0;
while (i<1000)
{
i;
//用户
}
或:
unsigned i;
i=1000;
do
i--;
//用户
while (i>0);
在这两种循环中使用do…while循环编译后生成代码长度短于while循环
7、查表
在中般不进行非常复杂运算如浮点数乘除及开方等以及些复杂
数学模型插补运算对这些即消耗时间又消费资源运算应尽量使用查表方
式并且将数据表置于存储区如果直接生成所需表比较困难也尽量在启
了减少了执行过程中重复计算工作量
8、其它
比如使用在线汇编及将串和些常量保存在存储器中均有利于优化
最新评论