適當(dāng)?shù)氖褂煤?/strong>
在 C程序中使用宏代碼可以提高程序的執(zhí)行效率。宏代碼本身不是函數(shù),但使用起來(lái)像函數(shù)。函數(shù)調(diào)用要使用系統(tǒng)的棧來(lái)保存數(shù)據(jù),同時(shí) CPU 在函數(shù)調(diào)用時(shí)需要保存和恢復(fù)當(dāng)前的現(xiàn)場(chǎng),進(jìn)行進(jìn)棧和出棧操作,所以函數(shù)調(diào)用也需要 CPU時(shí)間。而宏定義就沒(méi)有這個(gè)問(wèn)題:宏定義僅僅作為預(yù)先寫(xiě)好的代碼嵌入到當(dāng)前程序中,不產(chǎn)生函數(shù)調(diào)用,所占用的僅僅是一些空間,省去了參數(shù)壓棧,生成匯編語(yǔ)言的 call 調(diào)用,返回參數(shù),執(zhí)行 return等過(guò)程,從而提高了程序的執(zhí)行速度。雖然宏破壞了程序的可讀性,使排錯(cuò)更加麻煩,但對(duì)于嵌入式系統(tǒng),為了達(dá)到要求的性能,嵌入代碼常常是必須的做法。
此外,我們還要避免不必要的函數(shù)調(diào)用,請(qǐng)看下面的代碼:
[plain] view plain copy PRint?
1. void str_print( char *str )
2. {
3. int i;
4. for ( i = 0; i < strlen ( str ); i++ )
5. {
6. printf("%c",str[ i ] );
7. }
8. }
9. void str_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. }
請(qǐng)注意,這兩個(gè)函數(shù)的功能相似。然而,第一個(gè)函數(shù)調(diào)用strlen函數(shù)多次,而第二個(gè)函數(shù)只調(diào)用函數(shù)strlen一次。因此第二個(gè)函數(shù)性能明顯比第一個(gè)好。
在 C 語(yǔ)言中循環(huán)語(yǔ)句使用頻繁,提高循環(huán)體效率的基本辦法就是降低循環(huán)體的復(fù)雜性:
(1) 在多重循環(huán)中,應(yīng)將最長(zhǎng)的循環(huán)放在最內(nèi)層,最短的循環(huán)放在最外層。這樣可以減少 CPU跨切循環(huán)的次數(shù)。如例 1-1 的效率比 1-2 的效率要低:
[plain] view plain copy print?
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
例 1-1長(zhǎng)循環(huán)在外層,效率低;例 1-2長(zhǎng)循環(huán)在內(nèi)層,效率高。
(2) 如果循環(huán)體內(nèi)有邏輯判斷,并且循環(huán)次數(shù)大,應(yīng)把循環(huán)判斷移到循環(huán)體外。如例 2-1比例 2-2 多執(zhí)行了 K-1 次判斷,而且由于前者頻繁進(jìn)行判斷,打斷了循環(huán)"流水線(xiàn)"作業(yè),使得編譯器不能對(duì)循環(huán)進(jìn)行優(yōu)化處理,降低了效率。
[plain] view plain copy print?
1. for (i = 0; i < 10000; i++)
2. {
3. if (條件)
4. 語(yǔ)句;
5. else
6. 語(yǔ)句;
7. } // 例子 2-1 程序簡(jiǎn)潔但效率低
8. if (條件)
9. {
10. for (i = 0; i < 10000; i++)
11. 語(yǔ)句;
12. }
13. else
14. {
15. for (i = 0; i < 10000; i++)
16. 語(yǔ)句;
17. } // 例子 2-2 程序部簡(jiǎn)潔但效率高
switch 語(yǔ)句是 C 語(yǔ)言中常用的選擇語(yǔ)句, 在編譯時(shí)會(huì)產(chǎn)生if- else- if 嵌套代碼,并按照順序進(jìn)行比較,發(fā)現(xiàn)匹配時(shí),就跳轉(zhuǎn)到滿(mǎn)足條件的語(yǔ)句執(zhí)行。
當(dāng) switch 語(yǔ)句中的 case 標(biāo)號(hào)很多時(shí),為了減少比較的次數(shù),可以把發(fā)生頻率相對(duì)高的條件放到第一位或者把整個(gè) switch 語(yǔ)句轉(zhuǎn)化嵌套 switch 語(yǔ)句。把發(fā)生頻率高的 case 標(biāo)號(hào)放在最外層的 switch 語(yǔ)句中,發(fā)生相對(duì)頻率相對(duì)低的 case 標(biāo)號(hào)放在另外的 switch 語(yǔ)句中。如例 3 中,把發(fā)生率高的case 標(biāo)號(hào)放在外層的 switch 語(yǔ)句中,把發(fā)生頻率低的放在缺省的(default)內(nèi)層 switch 語(yǔ)句中。
[plain] view plain copy print?
1. switch (表達(dá)式)
2. {
3. case 值1:
4. 語(yǔ)句1: break;
5. case 值2:
6. 語(yǔ)句2:break;
7. ……
8. /*把發(fā)生頻率低的放在內(nèi)層的switch語(yǔ)句中*/
9. default:
10. switch (表達(dá)式)
11. {
12. case 值n:
13. 語(yǔ)句n: break;
14. case 值m:
15. 語(yǔ)句m: break;
16. ……
17. }
18. }
例子3 使用嵌套switch語(yǔ)句提高程序執(zhí)行效率。
考慮Fibonacci(斐波那契)問(wèn)題,F(xiàn)ibonacci問(wèn)題是可以通過(guò)簡(jiǎn)單的遞歸方法來(lái)解決:
[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開(kāi)始,因此,該系列看起來(lái):1,1,2,3,5,8,…
注意:從遞歸樹(shù),我們計(jì)算fib(3)函數(shù)2次,fib(2)函數(shù)3次。這是相同函數(shù)的重復(fù)計(jì)算。如果n非常大,fib函數(shù)的效率會(huì)比較低。Memoization是一個(gè)簡(jiǎn)單的技術(shù),可以被用在遞歸,加強(qiáng)計(jì)算速度。fibonacci 函數(shù)Memoization的代碼如下:
[plain] view plain copy print?
1. int calc_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. int fib( int n , int* value )
14. {
15. if ( value[ n ] != -1 )
16. {
17. return value[ n ]; // Using memoization
18. }
19. else
20. {
21. value[ n ] = fib( n - 2 , value ) + fib ( n - 1 , value ); // Computing the fibonacci term
22. }
23. return value[ n ]; // Returning the value
24. }
除了編程上的技巧外,為提高系統(tǒng)的運(yùn)行效率,我們通常也需要最大可能地利用各種硬件設(shè)備自身的特點(diǎn)來(lái)減小其運(yùn)轉(zhuǎn)開(kāi)銷(xiāo),例如減小中斷次數(shù),利用DMA傳輸方式等。
對(duì)于嵌入式系統(tǒng),C語(yǔ)言在開(kāi)發(fā)速度,軟件可靠性以及軟件質(zhì)量等方面都有著明顯的優(yōu)勢(shì)。本文就嵌入式C語(yǔ)言在系統(tǒng)開(kāi)發(fā)中,如何更好的利用系統(tǒng)資源,對(duì)代碼進(jìn)行優(yōu)化進(jìn)行了討論。當(dāng)然代碼優(yōu)化的方法還有很多,這里只是寫(xiě)出了一部分,希望能為開(kāi)發(fā)人員提供一些幫助,也歡迎大家留言交流。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注