嵌入式系统编程中的代码优化

3、实时C++编程入门:从基础概念到LED控制实践 本文介绍了C++在实时嵌入式系统中的应用,重点讲解了编程中的专业术语、语法特点以及类类型的使用。通过一个LED控制程序的实例,展示了如何利用C++进行嵌入式开发,并对代码进行了优化,提高了可读性和可维护性。 阅读详情

在当前计算机技术高度发展的今天,嵌入式系统已经广泛地应用于工业控制、信息家电、办公自动化、移动通信、仪器仪表、医疗电子以及国防等领域。随着国内外各种嵌入式产品的进一步开发和推广,嵌入式技术越来越和人们的生活紧密结合。

 

嵌入式系统一般指非PC系统,通常完成一种或多种特定的计算机功能。它是以应用为中心,软硬件可裁减的,适应应用系统对功能,可靠性,成本,体积,功耗等综合性要求的专用计算机系统。简单的说类似于PC中的BIOS的工作方式,具有软件代码小、高度自动化、响应速度快等特点。 特别适合于要求实时和多任务的应用体系。嵌入式实时系统是目前蓬勃发展的行业之一。但是,实时嵌入式系统的特点使得其软件受时间和空间的严格限制,加上运行环境复杂,使得嵌入式系统软件的开发变得异常困难。 为了设计一个满足功能、性能和时间要求的安全可靠的高性能嵌入式系统,编程语言的选择十分重要。

 

1、嵌入式系统中编程语言的选择

因为汇编语言编写的代码难懂,从而不好维护和难于调试,且只能针对特定的体系结构和处理器移植性差, 所以既不宜在复杂系统中使用,又不便于实现软件重用;而高级语言具有良好的通用性和丰富的软件支持,可移植性好、易于维护,因此高级语言编程具有许多优势。随着嵌入式系统应用范围的不断扩大和嵌入式实时操作系统RTOS(Real Time Operating System)的广泛使用,高级语言编程已是嵌入式系统设计的必然趋势。但是 不排除一些软件模块仍用汇编语言来写,这可以使程序更加有效。虽然C/C++编译器对代码进行了优化,但是适当的使用内联汇编指令可以有效的提高整个系统运行的效率。 目前,在嵌入式系统开发过程中使用的语言种类很多,但仅有少数几种语言得到了比较广泛的应用。其中C和C++是应用最广泛的。C++在支持现代软件工程、 OOP(Object Oriented Programming,面向对象的程序设计)、结构化等方面对C进行了卓有成效的改进,但在程序代码容量、执行速度、 程序复杂程度等方面比C语言程序性能差一些。由于C语言既有低级语言的直接控制硬件的能力,又有高级语言的灵活性,是目前在嵌入式系统中应用最广泛的编程语言。随着网络技术和嵌入式技术的不断发展,Java的应用也得到广泛应用。

 

2、实时程序设计中代码的优化

在嵌入式的系统开发中,出于对低价产品的需求, 硬件的设计者需要提供刚好足够的存储器和完成工作的处理能力。所以在嵌入式软件设计的最后一个阶段则变成了对代码的优化。

 

代码优化的目标是体积小和速度快,可以从算法、数据和指令流三方面来考虑。

 

算法优化

大多数情况下,速度同内存(或者是性能,比如说压缩性能)是不可兼得的。目前程序加速的常用算法一个大方面就是利用查表来避免计算(比如在jpg有huffman码表,在YUV到RGB变换也有变换表)这样原来的复杂计算现在仅仅查表就可以了,虽然浪费了内存,不过速度显著提升。此外在编写程序时还要注意提高效率,例如:

 

Switch语句中根据发生频率来进行case排序

switch语句是一个普通的编程技术,编译器会产生if-else-if的嵌套代码,并按照顺序进行比较,发现匹配时,就跳转到满足条件的语句执行。使用时需要注意。每一个由机器语言实现的测试和跳转仅仅是为了决定下一步要做什么,就把宝贵的处理器时间耗尽。为了提高速度,设法根据具体的情况按照它们发生的相对频率排序。换句话说,把最可能发生的情况放在第一位,最不可能的情况放在最后。

 

将大的switch语句转为嵌套switch语句

当switch语句中的case标号很多时,为了减少比较的次数,明智的做法是把大switch语句转为嵌套switch语句。把发生频率高的case 标号放在一个switch语句中,并且是嵌套switch语句的最外层,发生相对频率相对低的case标号放在另一个switch语句中。 如果switch中每一种情况下都有很多的工作要做,那么把整个switch语句用一个指向函数指针的表来替换会更加有效。

 

用指针代替数组

在许多种情况下,可以用指针运算代替数组索引,这样做常常能产生又快又短的代码。与数组索引相比,指针一般能使代码速度更快,占用空间更少。使用多维数组时差异更明显。下面的代码作用是相同的,但是效率不一样。

数组索引 指针运算

For(;;){ p=array

A=array[r++]; for(;;){

a=*(p++);

...... ......

} }

指针方法的优点是,array的地址每次装入地址p后,在每次循环中只需对p增量操作。在数组索引方法中,每次循环中都必须进行基于r值求数组下标的复杂运算。

 

使用宏函数而不是函数。例如:

#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时间。而宏函数不存在这个问题。宏函数仅仅作为预先写好的代码嵌入到当前程序,不会产生函数调用,所以仅仅是占用了空间,在频繁调用同一个宏函数的时候,该现象尤其突出。

 

Data optimization数据优化

比算法优化层低一级的是数据优化层,我们可以通过改变算法使用的数据类型来优化算法。主要的目的是使处理的数据和目标结构的特性相一致。这项优化不需要大量的代码重写,并独立于算法优化的执行而执行.例如:

 

确定浮点型变量和表达式是 float 型

为了让编译器产生更好的代码,必须确定浮点型变量和表达式是 float 型的。要特别注意的是,以 ";F"; 或 ";f"; 为后缀(比如:2.718f)的浮点常量才是 float 型,否则默认是 double 型。为了避免 float 型参数自动转化为 double,请在函数声明时使用 float。

 

使用32位的数据类型

编译器有很多种,但它们都包含的典型的32位类型是:int,signed,signed int,unsigned,unsigned int,long,signed long,long int,signed long int,unsigned long,unsigned long int。尽量使用32位的数据类型,因为它们比16位的数据甚至8位的数据更有效率。

 

明智使用有符号整型变量

在很多情况下,你需要考虑整型变量是有符号还是无符号类型的。在许多地方,考虑是否使用有符号的变量是必要的。在一些情况下,有符号的运算比较快;但在一些情况下却相反。 比如:整型到浮点转化时,使用大于16位的有符号整型比较快。因为x86构架中提供了从有符号整型转化到浮点型的指令,但没有提供从无符号整型转化到浮点的指令。在整数运算中计算商和余数时,使用无符号类型比较快。

 

Instruction flow optimization指令流优化

第三层优化的目标是低级指令流。比较常见的技术是循环合并(loop merging),循环展开(unrolling),软件流水(software pipelining)。

 

循环合并

如果两个循环计数差不多、循环执行互不相同的操作,可以把它们合并在一起组成一个循环。当两个循环的负荷都不满时,这是非常有用的。

 

循环展开

循环展开就是把循环计数小的循环展开,成为非循环形式的串行程序,或者把循环计数大的循环部分展开,减少循环迭代次数,这样可以节省了用于循环设置、初始化、增加和校对循环计数器的时间。大多数编译器可以自动完成这项工作,手工编译会出现错例如:

for( int i = 0; i < 3; i++ ) array[i] = i;

逻辑上等同于:

array[0] = 0; array[1] = 1, array[2] = 2;

 

软件流水

软件流水是用来安排循环指令,使这个循环多次迭代并行执行的一种技术。在嵌套循环中,编译器仅对最里面的循环执行软件流水,因此对执行周期很少的内循环作循环展开,外循环进行软件流水,这样可以改进C代码并行执行的性能。使用软件流水还应当注意:尽管软件流水循环可以包含内联函数,但是不能包含函数调用;在循环中不可以有条件终止指令;在循环体中不可以修改循环控制变量。

 

3、总结语

现代的C和C++编译器都提供了一定程度上的代码优化。然而,大部分由编译器执行的优化仅涉及执行速度和代码大小的一个平衡。你的程序能够变得更快或者更小,但是不可能又变快又变小。上面介绍的方法主要是为了提高代码的效率。但是事实上,在使用这些技术提高代码运行速度的同时会相应的产生一些负面的影响,比如增加代码的大小、降低程序可读性等。不过你可以让C/C++编 译器来进行减少代码大小的优化,而手动利用编程来减少代码的执行时间。在嵌入式程序设计中合理地使用这几种技术有时会达到很好 的优化效果。

 
18、ARM编程:从代码分析到Thumb代码运用 本文探讨了ARM编程中的多个关键主题,包括GNU编译器对ARM处理器的支持、除法运算的底层实现与优化、GCC生成代码的分析、逆向工程工具Ghidra的使用,以及Thumb代码的原理与应用场景。通过代码示例和工具实践,帮助开发者更好地理解ARM架构编程优化策略,适用于从嵌入式系统开发到高级应用分析的多个领域。 阅读详情

相关推荐

掌握嵌入式系统编程:C与C++的应用

《Programming Embedded Systems in C and C++》是迈克尔·巴尔所著,旨在向C和C++程序员介绍嵌入式系统的基础知识和高级技术。书中涵盖了从编写简单的嵌入式程序到优化代码性能的多个方面,包括内存测试、设备驱动设计、操作系统选择、代码优化等。本书不仅适用于嵌入式系统编程新手,也适合有经验的程序员深入学习。...

weixin_29476595的博客 254

嵌入式程序设计学习(5)

stm32嵌入式应用系统设计学习目标可视化的代码跟踪调试Proteus仿真运行stm32程序绘制一个stm32最小系统的电路原理图、PCB图总结参考文献 学习目标 一. 可视化的代码跟踪调试。“人靠衣装马靠鞍,狗配铃铛跑的欢”。在前次作业中命令行工具gdb调试基础上,练习利用各种可视化调试前端软件(后端依然依赖gcc、gdb)进行程序代码的跟踪查错,提供工作效率。可选择以下方法之一: 1.可视化前端 Kdbg。 2.可视化前端 Insight。有点older,不推荐。 3.基于跨平台多类型代码编辑器VSco

weixin_43281232的博客 338

Keil C51 8.08a:全面的嵌入式系统开发工具

Keil C51集成开发环境(IDE)的8.08a版本引入了无限制开发模式的概念。无限制模式意味着开发者可以摆脱以往版本中对程序大小或变量数量的限制。这种模式的引入,使得开发者能够更加专注于实现项目功能,而不必担心代码量超过限制导致编译失败。无限制模式的优势主要表现在以下几个方面:更大项目的支持:能够构建更大规模的工程,适合于复杂系统的开发。更高的灵活性:在项目规模增长时无需重构代码,节省时间与资源。增强的扩展性:允许开发者自由地添加库和模块,利于系统的持续升级和维护。

weixin_35749545的博客 619

位操作的详解

#define bwMCDR2_ADDRESS 4 #define bsMCDR2_ADDRESS 17 #define bmMCDR2_ADDRESS BIT_MASK (MCDR2_ADDRESS) #define BIT_MASK(_bf)(((1U (bs##_bf) #define SET_BITS(_dst,_bf,_val)\ ((_dst)=((_dst)&~(BIT

MarkHome 606

十一、移植优化---CONFIG 优化进 menuconfig(1)

  在移植 JZ2440 中,include/configs/jz2440.h 中有很多config 项都是已经在 uboot 的主配置中已经存在了的,这些配置造成了重复,需要优化。   先将原先的 smdk2410.h 拷贝进来:cp include/configs/smdk2410.h ../../u-boot-2018.03/include/configs/jz2440.h  ...

dongbipi3785的博客 489

实例分析嵌入式代码

1、SEG8c.s 首先是对数码管点亮方式的理解, 上课的时候老师将讲到用数码管显示的数字为31+80,怎么也想不通。 回来看到老师的逐个点亮数码管每一段的代码如下: myRCC.APB2ENR |= (1 << RCC_APB2ENR_bIOPEEN); // 使能PE PE.CRL = 0x22222222; /...

weixin_33712987的博客 849

C语言中可变参数的用法

C语言中可变参数的用法1   --------------------------------------------------------------------------------  资料文章  加入时间:2007-4-13 15:21:54  网络教育学院 张俊

特权份子的专栏 551

面向对象的嵌入式系统开发6-以框架为中心的嵌入式系统程序

面向对象的嵌入式系统开发6-以框架为中心的嵌入式系统程序  当一个应用系统完成了分析和设计活动后,就可是进入到编码实现阶段。嵌入式系统程序设计需要在特定开发环境下进行。如何在特定的开发环境下实现面向对象设计元素和根据系统的特定约束条件优化软件设计是程序设计中的重点内容。 6.1 嵌入式系统程序设计与通用计算程序设计的区别 &esmp;早期的嵌入式程序大度是用汇编语言开发的,但由于嵌入式系统本身所处理问题的规模不断增长和复杂性的不断增加,使得完全用汇编语言开发整个大型嵌入式系统已经成为不可能。作为一种

qq_43650963的博客 625

高效率嵌入式程序开发

嵌入式系统对应用软件的质量要求很高,在嵌入式开发中须注意对代码进行优化,尽可能地提高代码效率。虽然C编译器都提供了一定程度的代码优化,但大部分由编译器执行的优化技术仅涉及执行速度和代码大小的平衡,不可能使程序既快又小,因而必须在编写程序时采取必要的措施。本文针对高效率嵌入式程序开发提供了一些编程技巧,对实际系统开发具有重要作用。  关键词:编译器; 程序开发; 代码优化  引言

thinkpadlove的专栏 993

C语言嵌入式系统开发中的应用与优化策略

C语言嵌入式系统开发中保持着不可替代的地位,其贴近硬件的特性、高效的执行性能和丰富的工具链支持使其成为资源受限环境的理想选择。成功的嵌入式C程序不仅需要掌握语言本身,更需要深入理解目标硬件架构、实时系统原理和优化技术。通过合理的架构设计、精细的代码优化和严格的测试验证,可以开发出高效、可靠的嵌入式系统。随着物联网和边缘计算的兴起,C语言嵌入式领域的重要性将持续增强,对开发者的技能要求也将不断提高。

liqing1620的博客 393

世界编程语言排行榜 | 解析最受欢迎编程语言及其未来趋势

未来,随着技术的不断进步,新的编程语言将不断涌现,但JavaScript、Python和Java等语言仍然将在软件开发的世界中占据重要位置。Java作为一种成熟的编程语言,尽管近年来受到新兴语言的挑战,但依然保持着强大的生命力。Python紧随其后,凭借其简洁的语法和广泛的应用场景,成为数据科学、机器学习、人工智能等领域的首选语言。最后,随着硬件技术的不断发展,编译器优化技术也在不断创新。未来,随着量子计算和人工智能的发展,编译类语言编译器优化将迎来新的挑战和机遇,继续推动软件性能向更高的层次发展。

hbldvc_061的博客 192

TMS320F28335 DAC性能与DSP编程实战

数字信号处理器(DSP)在现代电子系统中扮演着至关重要的角色,特别是在需要高速数学运算的场合,如控制和信号处理。TMS320F28335 DSP是德州仪器(Texas Instruments)推出的一款性能卓越的32位定点处理器,以其高性能、高精度和快速处理能力,成为了工业控制、通信系统、电机驱动等众多应用领域的理想选择。

weixin_29069575的博客 828

C语言最新面试题系列二

好的嵌入式程序员非常准确地明白硬件的细节和它的局限,然而PC机程序往往把硬件作为一个无法避免的烦恼。10、这一问题测试你是否知道为了访问一绝对地址把一个整型数强制转换为一指针是合法的。12、这个问题测试你是否懂得C语言中的整数自动转换原则,我发现有些开发者懂得极少这些东西。13、对于一个int型不是16位的处理器为说,上面的代码是不正确的。14、 这里,我期望应试者能提到内存碎片,碎片收集的问题,变量的持行时间等等。16、 这个问题将做为这个测验的一个愉快的结尾。9、对这个问题有三种基本的反应。

关注我!带你一路 "狂飙" 到底! 1258

嵌入式软件开发,测试、找bug技巧

ICE一般都有一个比较特殊的CPU,称为外合(bond-out)CPU.这是一种被打开了封装的CPU,并且通过特殊的连接,可以访问到CPU的内部信号,而这些信号,在CPU被封装时,是没法 “看到”的。可以理解,因为代码不是他写的,他有足够的理由去 shitbug百出的代码,只要他自己不要写出这种代码,否则有一天同组的其它人可能同样会shit他写的代码。当你被问题难住时,关掉电脑,出去走走,把你的问题和你的朋友甚至你的小狗说说,或许他们可以给你意想不到的启发。不同的工具,有不同的使用范围,有不同的功能。

2401_83396023的博客 928
上一篇: 走向Linux系统高手之路 内核编译过程解析
下一篇: 嵌入式Linux的文件系统及其存储机制分析
menuconfig
博客等级 码龄19年 713粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值