《2022年C语言嵌入式系统编程修炼之性能优化 .pdf》由会员分享,可在线阅读,更多相关《2022年C语言嵌入式系统编程修炼之性能优化 .pdf(4页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、C 语言嵌入式系统编程修炼之性能优化使用宏定义在 C 语言中,宏是产生内嵌代码的唯一方法。对于嵌入式系统而言,为了能达到性能要求,宏是一种很好的代替函数的方法。写一个 标准 宏 MIN ,这个宏输入两个参数并返回较小的一个:错误做法:#define MIN(A,B) ( A = B ? A : B ) 正确做法:#define MIN(A,B) ( A)= (B) ? (A) : (B) ) 对于宏,我们需要知道三点:(1)宏定义 像函数;(2)宏定义不是函数,因而需要括上所有参数 ;(3)宏定义可能产生副作用。下面的代码:least = MIN(*p+, b); 将被替换为:( (*p+)
2、= (b) ?(*p+):(b) ) 发生的事情无法预料。因而不要给宏定义传入有副作用的参数 。使用寄存器变量当对一个变量频繁被读写时,需要反复访问内存,从而花费大量的存取时间。为此,C语言提供了一种变量,即寄存器变量。这种变量存放在CPU 的寄存器中,使用时,不需要访问内存,而直接从寄存器中读写,从而提高效率。寄存器变量的说明符是register 。对于循环次数较多的循环控制变量及循环体内反复使用的变量均可定义为寄存器变量,而循环计数是应用寄存器变量的最好候选者。(1) 只有局部自动变量和形参才可以定义为寄存器变量。因为寄存器变量属于动态存储方式, 凡需要采用静态存储方式的量都不能定义为寄存
3、器变量,包括:模块间全局变量、模块内全局变量、局部static 变量;(2) register是一个 建议 型关键字,意指程序建议该变量放在寄存器中,但最终该变量可能因为条件不满足并未成为寄存器变量,而是被放在了存储器中,但编译器中并不报错 (在C+语言中有另一个建议 型关键字: inline )。下面是一个采用寄存器变量的例子:/* 求 1+2+3+.+n的值*/ WORD Addition(BYTE n) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 4 页 - -
4、 - - - - - - - register i,s=0; for(i=1;i外部同步RAM外部异步 RAMFLASH/ROM 对于程序代码,已经被烧录在FLASH 或 ROM 中,我们可以让CPU 直接从其中读取代码执行,但通常这不是一个好办法,我们最好在系统启动后将FLASH 或 ROM 中的目标代码拷贝入RAM 中后再执行以提高取指令速度;对于 UART 等设备, 其内部有一定容量的接收BUFFER ,我们应尽量在BUFFER被占满后再向 CPU 提出中断。例如计算机终端在向目标机通过RS-232 传递数据时,不宜设置UART 只接收到一个BYTE 就向 CPU 提中断,从而无谓浪费中
5、断处理时间;如果对某设备能采取DMA 方式读取, 就采用 DMA 读取,DMA 读取方式在读取目标中包含的存储信息较大时效率较高,其数据传输的基本单位是块,而所传输的数据是从设备直接送入内存的(或者相反)。DMA 方式较之中断驱动方式,减少了CPU 对外设的干预,进一步提高了CPU 与外设的并行操作程度。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 4 页 - - - - - - - - - 活用位操作使用 C 语言的位操作可以减少除法和取模的运算。在计算机程序中数据的
6、位是可以操作的最小数据单位,理论上可以用位运算 来完成所有的运算和操作,因而,灵活的位操作可以有效地提高程序运行的效率。举例如下:/* 方法 1 */ int i,j; i = 879 / 16; j = 562 % 32; /* 方法 2 */ int i,j; i = 879 4; j = 562 - (562 5 5); 对于以 2 的指数次方为 *、 /或% 因子的数学运算,转化为移位运算 通常可以提高算法效率。因为乘除运算指令周期通常比移位运算大。C 语言位运算除了可以提高运算效率外,在嵌入式系统的编程中,它的另一个最典型的应用,而且十分广泛地正在被使用着的是位间的与(&)、或( |
7、)、非( )操作,这跟嵌入式系统的编程特点有很大关系。我们通常要对硬件寄存器进行位设置,譬如,我们通过将AM186ER型 80186 处理器的中断屏蔽控制寄存器的第低6 位设置为0(开中断2),最通用的做法是:#define INT_I2_MASK 0 x0040 wTemp = inword(INT_MASK); outword(INT_MASK, wTemp &INT_I2_MASK); 而将该位设置为1 的做法是:#define INT_I2_MASK 0 x0040 wTemp = inword(INT_MASK); outword(INT_MASK, wTemp | INT_I2_M
8、ASK); 判断该位是否为1 的做法是:#define INT_I2_MASK 0 x0040 wTemp = inword(INT_MASK); if(wTemp & INT_I2_MASK) /* 该位为 1 */ 上述方法在嵌入式系统的编程中是非常常见的,我们需要牢固掌握。总结在性能优化方面永远注意80-20 准备,不要优化程序中开销不大的那80%,这是劳而无功的。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 4 页 - - - - - - - - - 宏定义是C
9、 语言中实现类似函数功能而又不具函数调用和返回开销的较好方法,但宏在本质上不是函数,因而要防止宏展开后出现不可预料的结果,对宏的定义和使用要慎而处之。很遗憾,标准C 至今没有包括C+ 中 inline 函数的功能, inline 函数兼具无调用开销和安全的优点。使用寄存器变量、内嵌汇编和活用位操作也是提高程序效率的有效方法。除了编程上的技巧外,为提高系统的运行效率,我们通常也需要最大可能地利用各种硬件设备自身的特点来减小其运转开销,例如减小中断次数、利用DMA 传输方式等。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 4 页 - - - - - - - - -