嵌入式C语言优化方案

1.引言

嵌入式系统是指完成一种或几种特定功能的计算机系统,
具有自动化程度高、响应速度快等优点, 目前已广泛应用于消费
电子、工业控制等领域。嵌入式系统受其使用的硬件以及运行环
境的限制, 非常注重代码的时空效率, 因此选择一种合适的开发
语言十分重要。目前, 在嵌入式系统开发中可使用的语言很多,
其中 C语言应用得最广泛。虽然用 C 语言编程具有许多优点,
但基于嵌入式系统的 C语言和标准 C语言又有很大区别。本文
结合嵌入式系统的特点, 讨论在程序设计中代码优化的一些方
法。

2.嵌入式C语言的特点

    作为一种结构化程序设计语言, C 语言兼顾多种高级语言
的特点, 具有很强的功能性和可移植性。但在嵌入式系统开发
中, 出于对低价产品的需求, 系统的计算能力和存储容量都非常
有限, 因此如何利用好这些资源就显得十分重要。开发人员应注
意嵌入式 C语言和标准 C 语言的区别, 减少生成代码长度
高程序执行效率, 在程序设计中对代码进行优化

3.C代码在程序中的优化

    现在的 C 编译器会自动对代码进行优化, 但这些优化是
执行速度和代码长度的平衡。如果要获得更小且执行效率更高
的代码, 需要程序员手工对代码进行优化

4.变量类型的定义

    
      不同的数据类型所生成的机器代码长度相差很多, 变量类型选
取的范围越小运行速度越快、占用的内存越少。比如 int 型变量
比 long型变量代码长度短、运行速度快, 相同类型的数据类型有
无符号对机器代码长度也有影响。因此我们应按照实际需要合
理的选用数据类型。

 5.算法优化

    算法优化指对程序时空复杂度的优化: 在 PC 机上进行程
序设计时一般不必过多关注程序代码的长短, 只需考虑功能的
实现, 但嵌入式系统就必须考虑系统的硬件资源。在程序设计
时, 应尽量采用生成代码短的算法, 在不影响程序功能实现的情
况下优化算法。

6.适当的使用宏

    在 C程序中使用宏代码可以提高程序的执行效率。宏代码
本身不是函数, 但使用起来像函数。函数调用要使用系统的栈来
保存数据, 同时 CPU 在函数调用时需要保存和恢复当前的现
场, 进行进栈和出栈操作, 所以函数调用也需要 CPU时间。而宏
定义就没有这个问题: 宏定义仅仅作为预先写好的代码嵌入到
当前程序中, 不产生函数调用, 所占用的仅仅是一些空间, 省去
了参数压栈、生成汇编语言的 call 调用、返回参数、执行 return
等过程, 从而提高了程序的执行速度。虽然宏破坏了程序的可读
性,使排错更加麻烦, 但对于嵌入式系统, 为了达到要求的性能,
嵌入代码常常是必须的做法。

7.提高循环语言的效率

    在 C 语言中循环语句使用频繁, 提高循环体效率的基本办法就是降低循环体的复杂性:        

         (1)在多重循环中, 应将最长的循环放在最内层, 最短的循环
放在最外层。这样可以减少 CPU跨切循环的次数。如例 1- 1 的
效率比 1- 2 的效率要低:

for (j = 0; j < 30; j++){
    for (i = 0; i < 10; i++){
        ... ...
    } 
} // 例子 1-1

for (i = 0; i < 10; i++){
    for (j = 0; j < 30; j++){
        ... ...
    }
} // 例子 1-2

例 1- 1 长循环在外层, 效率低 例 1- 2 长循环在内层, 效率高

        (2) 如果循环体内有逻辑判断, 并且循环次数大, 应把循环
判断移到循环体外。如例 2- 1 比例 2- 2 多执行了 K- 1 次判断,
而且由于前者频繁进行判断, 打断了循环"流水线"作业, 使得编
译器不能对循环进行优化处理, 降低了效率

for (i = 0; i < 10000; i++){
    if (条件)
        语句;
     else
        语句;
} // 例子 2-1 程序简洁但效率低

if (条件){
    for (i = 0; i < 10000; i++)
       语句;
} else {
    for (i = 0; i < 10000; i++)
       语句;
} // 例子 2-2 程序部简洁但效率高

 8.提高 switch 语句的效率    

    switch 语句是 C 语言中常用的选择语句, 在编译时会产生
if- else- if 嵌套代码, 并按照顺序进行比较, 发现匹配时, 就跳转
到满足条件的语句执行。

    当 switch 语句中的 case 标号很多时,
为了减少比较的次数, 可以把发生频率相对高的条件放到第一
位或者把整个 switch 语句转化嵌套 switch 语句。把发生频率高
的 case 标号放在最外层的 switch 语句中, 发生相对频率相对低
的 case 标号放在另外的 switch 语句中。如例 3 中,把发生率高的
case 标号放在外层的 switch 语句中, 把发生频率低的放在缺省
的(default)内层 switch 语句中。

switch (表达式){
    case 值1:
        语句1: break;
    case 值2:
          语句2:break;
    ... ...
    /*把发生频率低的放在内层的switch语句中*/
    default:
        switch (表达式){
            case 值n:
                语句n: break;
            case 值m:
                语句m: break;
            ... ...
        }
}

例子3 使用嵌套switch语句提高程序执行效率

9.避免使用标准库

    使用 C语言标准库可以加快开发进度, 但由于标准库需要
设法处理用户所有可能遇到的情况, 所以很多标准库代码很多。
比如标准库中的 sprintf函数非常大。这个庞大的代码中有很大
一部分用于处理浮点数, 如果程序中不需要格式化浮点数值
( 如%f) , 程序设计人员就可以根据实际情况用少量的代码实现
这个功能。

10.采用数学方法优化程序

    数学是计算机之母, 没有数学的依据和基础, 就没有计算机
的发展, 所以在编写程序的时候, 采用一些数学方法会对程序的
执行效率有数量级的提高。有时候这个问题常常被大家忽略, 对
于没有经验的程序员来说更是如此。例如: 求 1~100 的和

sum = 100*(100+1)/2; 数学公式. (a1 + an)*n/2

用位操作区代替除法

比如: 128 / 8 ->> 128 >> 3;

    优化算法和数据结构对提高代码的效率有很大的帮助。当
然有时候时间效率和空间效率是对立的, 此时应分析哪个更重
要, 做出适当的折中。另外, 在进行优化的时候不要片面的追求
紧凑的代码, 因为紧凑的代码并不能产生高效率的机器码

11.存储器分配

    由于成本限制, 嵌入式系统存储器容量有限。程序中所有
的变量、包含的库函数以及堆栈等都使用有限的内存: 全局变量
在整个程序范围内都有效, 程序执行完后才会释放; 静态变量的
作用范围也是整个程序, 只有局部变量中的动态变量在函数执
行完后会释放。因此, 在程序中应尽量使用局部变量, 提高内存
使用效率。程序中堆的大小受限于所有全局数据和栈空间都分
配后的剩余量, 如果堆太小, 程序不能够在需要的时候分配内
存。因此在使用 malloc 函数申请内存之后一定要用 free 函数进
行释放, 防止内存泄露。

 

 

 

你可能感兴趣的:(嵌入式C语言优化方案)