嵌入式系统是指完成一种或几种特定功能的计算机系统,具有自动化程度高,响应速度快等优点,目前已广泛应用于消费电子,工业控制等领域。嵌入式系统受其使用的硬件以及运行环境的限制,非常注重代码的时间和空间效率,因此选择一种合适的开发语言十分重要。 目前,在嵌入式系统开发中可使用的语言很多,其中 C语言应用得最广泛。虽然用 C 语言编程具有许多优点,但基于嵌入式系统的C语言和标准 C语言又有很大区别。接下来《单片机与嵌入式系统应》小编结合嵌入式系统的特点和高手们的一些积累,给大家整理出在程序设计中代码优化的一些小技巧。 此外,我们还要避免不必要的函数调用,请看下面的代码: [plain] view plain copy print? 1.voidstr_print(char *str ) 2. { 3.int i; 4.for ( i = 0; i < strlen ( str ); i++ ) 5. { 6. printf("%c",str[ i ] ); 7. } 8. } 9.voidstr_print1 (char *str ) 10. { 11.int len; 12. len = strlen ( str ); 13.for ( i = 0; i < len; i++ ) 14. { 15. printf("%c",str[ i ] ); 16. } 17. } 请注意,这两个函数的功能相似。然而,第一个函数调用strlen函数多次,而第二个函数只调用函数strlen一次。因此第二个函数性能明显比第一个好。 (1) 在多重循环中,应将最长的循环放在最内层,最短的循环放在最外层。这样可以减少 CPU跨切循环的次数。如例 1-1 的效率比 1-2 的效率要低: [plain] view plain copyprint? 1.for (j = 0; j < 30; j++) 2. { 3.for (i = 0; i < 10; i++) 4. { 5. …… 6. } 7. 8. } // 例子 1-1 9.for (i = 0; i < 10; i++) 10. { 11.for (j = 0; j < 30; j++) 12. { 13. …… 14. } 15. 16. } // 例子 1-2 [plain] view plain copyprint? 1.for (i = 0; i < 10000; i++) 2. { 3.if (条件) 4. 语句; 5.else 6. 语句; 7. } // 例子 2-1 程序简洁但效率低 8.if (条件) 9. { 10.for (i = 0; i < 10000; i++) 11. 语句; 12. } 13.else 14. { 15.for (i = 0; i < 10000; i++) 16. 语句; 17. } // 例子 2-2 程序部简洁但效率高 当 switch 语句中的 case 标号很多时,为了减少比较的次数,可以把发生频率相对高的条件放到第一位或者把整个 switch 语句转化嵌套 switch 语句。把发生频率高的 case 标号放在最外层的 switch 语句中,发生相对频率相对低的 case 标号放在另外的 switch 语句中。如例 3 中,把发生率高的case 标号放在外层的 switch 语句中,把发生频率低的放在缺省的(default)内层 switch 语句中。 [plain] view plain copy print? 1. switch (表达式) 2. { 3. case 值1: 4. 语句1: break; 5. case 值2: 6. 语句2:break; 7. …… 8. /*把发生频率低的放在内层的switch语句中*/ 9. default: 10. switch (表达式) 11. { 12. case 值n: 13. 语句n: break; 14. case 值m: 15. 语句m: break; 16. …… 17. } 18. } 例子3 使用嵌套switch语句提高程序执行效率。 sum = 100*(100+1)/2; 数学公式: (a1 + an)*n/2 使用C语言的位操作可以减少除法和取模的运算。在计算机程序中数据的位是可以操作的最小数据单位,理论上可以用“位运算”来完成所有的运算和操作。因而,灵活的位操作可以有效地提高程序运行的效率。比如用用位操作区代替除法:比如:128 / 8 ->> 128 >> 3; 优化算法和数据结构对提高代码的效率有很大的帮助。当然有时候时间效率和空间效率是对立的,此时应分析哪个更重要, 做出适当的折中。另外,在进行优化的时候不要片面的追求紧凑的代码,因为紧凑的代码并不能产生高效率的机器码。 编译前: while (1); 编译后: moveax,1 testeax,eax jefoo+23h jmpfoo+18h 编译前: for (;;); 编译后: jmp foo+23h 显然,for (;;)指令少,不占用寄存器,而且没有判断,跳转,比while (1)好。 [plain] view plain copy print? 1. int fib ( n ) 2. { 3. if ( n == 0 || n == 1 ) 4. { 5. return 1; 6. } 7. else 8. { 9. return fib( n - 2 ) + fib ( n - 1 ); 10. } 11. } 注:在这里,我们考虑Fibonacci 系列从1开始,因此,该系列看起来:1,1,2,3,5,8,… 注意:从递归树,我们计算fib(3)函数2次,fib(2)函数3次。这是相同函数的重复计算。如果n非常大,fib函数的效率会比较低。Memoization是一个简单的技术,可以被用在递归,加强计算速度。fibonacci 函数Memoization的代码如下: [plain] view plain copy print? 1.intcalc_fib (int n ) 2. { 3.int val[ n ] , i; 4.for ( i = 0; i <=n; i++ ) 5. { 6. val[ i ] = -1; // Value of the first n + 1 terms of the fibonacci terms set to -1 7. } 8. val[ 0 ] = 1; // Value of fib ( 0 ) is set to 1 9. val[ 1 ] = 1; // Value of fib ( 1 ) is set to 1 10.return fib( n , val ); 11. } 12. 13.intfib(int n , int* value) 14. { 15.if ( value[ n ] != -1 ) 16. { 17.returnvalue[ n ]; // Using memoization 18. } 19.else 20. { 21.value[ n ] = fib( n - 2 , value ) + fib ( n - 1 , value ); // Computing the fibonacci term 22. } 23.returnvalue[ n ]; // Returning the value 24. } 除了编程上的技巧外,为提高系统的运行效率,我们通常也需要最大可能地利用各种硬件设备自身的特点来减小其运转开销,例如减小中断次数,利用DMA传输方式等。 对于嵌入式系统,C语言在开发速度,软件可靠性以及软件质量等方面都有着明显的优势。本文就嵌入式C语言在系统开发中,如何更好的利用系统资源,对代码进行优化进行了讨论。当然代码优化的方法还有很多,这里只是写出了一部分,希望能为开发人员提供一些帮助,也欢迎大家留言交流。 -END- 免责声明:整理文章为传播相关技术,版权归原作者所有,如有侵权,请联系删除 ---------------------------------------------------------------------------------------------------------------------- 我们尊重原创,也注重分享,文章来源于微信公众号:嵌入式ARM,建议关注公众号查看原文。如若侵权请联系qter@qter.org。 ---------------------------------------------------------------------------------------------------------------------- |