嵌入式系统编程中的代码优化
2008-02-23 05:32:06来源:互联网 阅读 ()
在当前电脑技术高度发展的今天,嵌入式系统已广泛地应用于工业控制、信息家电、办公自动化、移动通信、仪器仪表、医疗电子连同国防等领域。随着国内外各种嵌入式产品的进一步研发和推广,嵌入式技术越来越和人们的生活紧密结合。
嵌入式系统一般指非PC系统,通常完成一种或多种特定的电脑功能。他是以应用为中央,软件和硬件可裁减的,适应应用系统对功能,可靠性,成本,体积,功耗等综合性需要的专用电脑系统。简单的说类似于PC中的BIOS的工作方式,具备软件代码小、高度自动化、响应速度快等特点。 特别适合于需要实时和多任务的应用体系。嵌入式实时系统是现在蓬勃发展的行业之一。但是,实时嵌入式系统的特点使得其软件受时间和空间的严格限制,加上运行环境复杂,使得嵌入式系统软件的研发变得异常困难。 为了设计一个满足功能、性能和时间需要的安全可靠的高性能嵌入式系统,编程语言的选择十分重要。
2 嵌入式系统中编程语言的选择
因为汇编语言编写的代码难懂,从而不好维护和难于调试,且只能针对特定的体系结构和处理器移植性差, 所以既不宜在复杂系统中使用,又不便于实现软件重用;而高级语言具备良好的通用性和丰富的软件支持,可移植性好、易于维护,因此高级语言编程具备许多优势。随着嵌入式系统应用范围的不断扩大和嵌入式实时操作系统RTOS(Real Time Operating System)的广泛使用,高级语言编程已是嵌入式系统设计的必然趋势。但是 不排除一些软件模块仍用汇编语言来写,这能够使程式更加有效。虽然C/C 编译器对代码进行了优化,但是适当的使用内联汇编指令能够有效的提高整个系统运行的效率。 现在,在嵌入式系统研发过程中使用的语言种类很多,但仅有少数几种语言得到了比较广泛的应用。其中C和C 是应用最广泛的。C 在支持现代软件工程、 OOP(Object Oriented Programming,面向对象的程式设计)、结构化等方面对C进行了卓有成效的改进,但在程式代码容量、执行速度、 程式复杂程度等方面比C语言程式性能差一些。由于C语言既有低级语言的直接控制硬件的能力,又有高级语言的灵活性,是现在在嵌入式系统中应用最广泛的编程语言。随着网络技术和嵌入式技术的不断发展,Java的应用也得到广泛应用。
3 实时程式设计中代码的优化
在嵌入式的系统研发中,出于对低价产品的需求, 硬件的设计者需要提供刚好足够的存储器和完成工作的处理能力。所以在嵌入式软件设计的最后一个阶段则变成了对代码的优化。
代码优化的目标是体积小和速度快,能够从算法、数据和指令流三方面来考虑。
3.1 算法优化
大多数情况下,速度同内存(或是性能,比如说压缩性能)是不可兼得的。现在程式加速的常用算法一个大方面就是利用查表来避免计算(比如在jpg有huffman码表,在YUV到RGB变换也有变换表)这样原来的复杂计算现在仅仅查表就能够了,虽然浪费了内存,但是速度显著提升。此外在编写程式时还要注意提高效率,例如:
3.1.1Switch语句中根据发生频率来进行case排序
switch语句是个普通的编程技术,编译器会产生if-else-if的嵌套代码,并按照顺序进行比较,发现匹配时,就跳转到满足条件的语句执行。使用时需要注意。每一个由机器语言实现的测试和跳转仅仅是为了决定下一步要做什么,就把宝贵的处理器时间耗尽。为了提高速度,设法根据具体的情况按照他们发生的相对频率排序。换句话说,把最可能发生的情况放在第一位,最不可能的情况放在最后。
3.1.2将大的switch语句转为嵌套switch语句
当switch语句中的case标号很多时,为了减少比较的次数,明智的做法是把大switch语句转为嵌套switch语句。把发生频率高的case 标号放在一个switch语句中,并且是嵌套switch语句的最外层,发生相对频率相对低的case标号放在另一个switch语句中。 假如switch中每一种情况下都有很多的工作要做,那么把整个switch语句用一个指向函数指针的表来替换会更加有效。
3.1.3用指针代替数组
在许多种情况下,能够用指针运算代替数组索引,这样做常常能产生又快又短的代码。和数组索引相比,指针一般能使代码速度更快,占用空间更少。使用多维数组时差异更明显。下面的代码作用是相同的,但是效率不相同。
数组索引 指针运算
For(;;){ p=array
A=array[r ]; for(;;){
a=*(p );
...... ......
} }
指针方法的长处是,array的地址每次装入地址p后,在每次循环中只需对p增量操作。在数组索引方法中,每次循环中都必须进行基于r值求数组下标的复杂运算。
3.1.4使用宏函数而不是函数。例如:
#define bwMCDR2_ADDRESS 4
#define bsMCDR2_ADDRESS 17
#define bmMCDR2_ADDRESS BIT_MASK(MCDR2_ADDRESS)
#define BIT_MASK(__bf) (((1U << (bw ## __bf)) - 1) << (bs ## __bf))
#define SET_BITS(__dst, __bf, __val) ((__dst) = ((__dst) & ~(BIT_MASK(__bf))) | (((__val) << (bs ## __bf)) & (BIT_MASK(__bf))))
SET_BITS(MCDR2, MCDR2_ADDRESS, RegisterNumber);
函数和宏函数的区别就在于,宏函数占用了大量的空间,而函数占用了时间。函数调用是要使用系统的栈来保存数据的,假如编译器里有栈检查选项,一般在函数的头会嵌入一些汇编语句对当前栈进行检查;同时,CPU也要在函数调用时保存和恢复当前的现场,进行压栈和弹栈操作,所以,函数调用需要一些CPU时间。而宏函数不存在这个问题。宏函数仅仅作为预先写好的代码嵌入到当前程式,不会产生函数调用,所以仅仅是占用了空间,在频繁调用同一个宏函数的时候,该现象尤其突出。
3.2 Data optimization数据优化
比算法优化层低一级的是数据优化层,我们能够通过改变算法使用的数据类型来优化算法。主要的目的是使处理的数据和目标结构的特性相一致。这项优化无需大量的代码重写,并单独于算法优化的执行而执行.例如:
3.2.1确定浮点型变量和表达式是 float 型
为了让编译器产生更好的代码,必须确定浮点型变量和表达式是 float 型的。要特别注意的是,以 ";F"; 或 ";f"; 为后缀(比如:2.718f)的浮点常量才是 float 型,否则默认是 double 型。为了避免 float 型参数自动转化为 double,请在函数声明时使用 float。
3.2.2使用32位的数据类型
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇: 嵌入式系统的构建
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash