嵌入式程式设计中C/C 代码的优化

2008-02-23 05:32:16来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

摘要:本文介绍了在嵌入式程式设计中几种提高C/C 代码效率的方法,通过对例子的分析,探讨了影响程式效率的原因。
关键词:c语言,c ,嵌入式,优化

1 引言
嵌入式电脑系统是指完成特定功能的电脑系统,他具备软件代码小,自动化程度高,响应速度快等特点。特别适合于需要实时和多任务的应用体系。由于嵌入式系统受时间、空间和运行环境的严格限制,使得嵌入式系统软件的研发变得很困难,为了研发出高性能的嵌入式系统,研发语言的选择十分关键。
现在,在嵌入式系统研发过程中可使用的语言很多,其中C和C 应用得最广泛。C 在面向对象、结构化等方面对C进行了改进,但在程式代码容量、执行速度等方面性能不如C语言。C语言既有低级语言的直接控制硬件的能力,又有高级语言的灵活性,在嵌入式系统中得到了最广泛的应用。在嵌入式的系统研发中,出于对低价产品的需求,硬件的设计者需要提供刚好足够的存储器和完成工作的处理能力。所以在嵌入式软件设计的最后一个阶段变成了对代码的优化阶段。
经过本人在嵌入式系统设计过程中的实践,下面介绍几种简单且行之有效的C/C 代码的优化方法。考虑到读者已学过了C/C 的原理,有一些已是经验丰富的编程员,本文的叙述将尽可能深入浅出。

2 变量的处理
开始编程时,一般首先碰到的是初始化的问题。建议使用英文单词的缩写代表变量,比如代表高度指针的变量可取名highpoint 或简写为hiptr。用缩写减少字母可加快程式的运行速度并减少占用的内存。另外变量类型选取的范围越小运行速度越快占用的内存越少。比如int型变量比long型变量运行速度越快,但变量类型选取的范围越小算术运算时越容易产生溢出错误。
在声明局部变量的时候能够使用寄存器变量register关键字。这就使得编译器把变量放入寄存器中,而不是在堆栈中,合理使用这种方法能够提高执行速度。函数调用越频繁,提高代码的效率越明显。
当使用变量作为函数返回值时,当变量值很大时,将花费很多的复制时间。参数返回没有变量返回的复制时间的问题,在时间上要快。但参数返回破坏了参数值,在安全性能上和函数的重复使用性能上差。建议在编程时,小的常量返回可用变量,小的变量返回用指针,大的常量返回可用参数或静态方法。另外,使用全局变量比函数传递参数更加有效率。这样做去除了函数调用参数入栈和函数完成后参数出栈所需的时间。然而,决定使用全局变量会影响程式的模块化和重入,故要慎重使用。

3 数组的处理
(1)数组在使用前需要对其先初始化。一种提高速度的方法是数组的范围在初始化时空着不添,这样程式运行的速度会更快。以函数引用数组为例:
void p(int a[6][3]){
for(int j=0;j<2;j )
a[j][2]=j;
}
和之对应的函数
void p(int a[][3]){
for(int j=0;j<2;j )
a[j][2]=j;
}
两种编程方法产生的结果完全相同,后一种方法由于数组[]内的数字不添,在执行时将由数组自动加入,结果会使程式运行的速度更快。同时也避免由于事前初始化数组时定义的范围过大而带来不必要的存储器浪费。
(2)用指针代替数组,这样做常常能产生又快又短的代码。和数组索引相比,指针一般能使代码速度更快,占用空间更少。指针方法的长处是装入地址后,在每次循环中,只需增量操作。而在数组索引方法中,每次循环中都必须进行基于数组下标的复杂运算。
(3)enum 方法常用于处理字符串数组。他有两个特点:(1)使数组中数自动排列(2)将数组中的数和字符串一一对应,以后处理字符串时使用相应的数字。enum使字符串的处理以数字的速度运行,而数字的处理速度比字符串的要快得多。enum的另一长处是自动加一。举例来说:
enum Months{JAN=1,FEB,MAR,APR,MAY}。
定义一个数字串数组Months,当数组的第一个变量赋值为1时,其他变量自动加一(FEB=2,MAR=3,-----)。

4 算数运算
简化数学表达式能够提高运算速度,这是个基本的常识。下面举几个简化数学运算的例子:
(1) int a=a*b a*c;
将程式改为:
int a=a*(b c);
两种编程方法产生的结果相同,后一种方法由于等号右边减少了一次乘法运算,节省了时间加快了速度。
(2) int a=2,b=256;
a= a*32 b/64;
将程式改为:
int a=2, b=256;
a=(a<<5) (b>>6);
两种编程方法在逻辑上完全相同,因为但通过移位进行2的整数次幂的乘除法要比直接进行乘除法运算速度快,所以后一种编程所需的运算时间短。
(3) int d=a/c+b/c;
和之对应的
int d=(a+b)*(1/c)
在不改变表达式含义的情况下,因为乘法运算比除法运算的度快,所以后一个表达式运算的速度快。
(4)假如精度许可,运算数据的位数选取应尽量短。当运算的数据超过CPU一次所能处理的最大数据时,CPU在系统管理下一般会对位数超过的大数自动分割处理,但这会使运算速度减慢。比如在16位机中,假如两相加数的位数都小于或等于15位,两数的运算在CPU中都可一次完成。当两相加数的位数都为17位时,两数的运算在CPU中需两次才能完成。在精度许可的前提下,假如想减少运算时间,应尽量使两个数的运算在CPU中一次完成,以提高运算速度。从存储 方面来说,存储数据的位数大将使存储控制器的负担过重,使他的处理速度变慢。需要注意的是,位数过大的数在存储器中造成的运算速度变慢的情况常常比在CPU中更严重。

5 函数调用
函数调用属于嵌套,分层的优秀编程方法,但他使程式处理的时间长,同时他占用的内存较多,同时使运算速度变慢,即他这一方法是有代价的。先说函数调用,
int d=appl(5,4,3);
int appl(int a,int b,int c){
int d=a*b*c;
return d;
}
在逻辑上这就等同于
int a=5, b=4, c=3;
int d=a*b*c;
第二个种方法运行的速度快,但灵活性差,不便于管理。将函数调用改为大的单一程式虽然使程式运行的速度更快,但编写,调试和维护是很不容易的。
再举例来说,调用一次函数int add1(int a, int b ){return a= a*a b*b}等同于重复调用两次函数int add2(int a){return a=a*a;}然后再相加两次调用的结果。但调用两次add2函数需分别在内存中建立和释放两次资源,所用的时间要比调用一次函数增加近一倍。所以编程时,需要考虑如何在方便的调试维护和程式运行效率之间寻找平衡点。

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇: C语言嵌入式系统编程之屏幕操作

下一篇: C 模板的定制三:部分定制C 类