中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開(kāi)通VIP
如何優(yōu)化代碼

如何優(yōu)化代碼

編程 2010-05-25 23:10:09 閱讀99 評(píng)論1   字號(hào): 訂閱

縮小編譯代碼 size 的幾種方式:

(A)    邏輯與算法:

合理的工作邏輯與算法. 一般而言, Code 永遠(yuǎn)是工程師的邏輯思維的體現(xiàn). 無(wú)論是實(shí)現(xiàn) function target or 構(gòu)建 system struction, 邏輯思維的能力高低, 對(duì) code size 具有深度影響(甚至對(duì)整個(gè) project 的成功實(shí)現(xiàn), 具有決定性的影響).

 

(B) 編譯器的配置:

1. 將編譯器的 size 優(yōu)化調(diào)整到 high級(jí)別.

2.   如果我們是 arm 的 user, 應(yīng)選擇 Thumb mode, 而不是 Arm mode.

我們無(wú)意在這里討論16-bit thumb指令集 與 32-bit arm 指令集有何具體異同. 我們僅僅從 mcu 的datasheet 中尋找到如下解釋(討論了兩者最終表現(xiàn)力): “工作在與 arm mode 相同的 32-bit 寄存器上, thumb code 保持了絕大部分的 arm 的表現(xiàn)力(的同時(shí)), Thumb code能夠提供高達(dá) 65% 的(作為比較的)arm code size.”

 

(C) 謹(jǐn)慎使用任何標(biāo)準(zhǔn)/編譯器提供的 C Library function:

謹(jǐn)慎使用編譯器提供的任何C Library function, 如果必需, 盡量自行完成需要的函數(shù)功能.

1. 謹(jǐn)慎使用string相關(guān)函數(shù)

無(wú)論是 sprintf(), atoi(), ntop(),都會(huì)帶來(lái)size 的顯著增加. 如有可能, 我們應(yīng)當(dāng)自行完成我們需要的類似的 functions.

 

2. 謹(jǐn)慎使用 time 相關(guān)函數(shù): 舉例說(shuō) localtime(), etc 等函數(shù).

 

3.   謹(jǐn)慎使用 math 函數(shù), 盡量不要包含 math.h
作為兩個(gè)比較的的例子是, 在同等編譯條件下, fasbs()可能多耗費(fèi) about 200bytes. sqrt() 可能會(huì)多耗費(fèi) about 3.5k bytes.

 

(D) 數(shù)據(jù)類型與編程習(xí)慣

1.       盡量避免 char(U8/S8), short(U16/S16) 的定義, 而使用 int(U32/S32) 的定義.

對(duì)于從 8-bit來(lái)到 arm world 的 engineer, 可能份外不習(xí)慣這個(gè)轉(zhuǎn)變吧?

C/C++ compiler reference document 明確指出: 只要可能, 就應(yīng)使用 int or long 來(lái)替代 char or short, 從而避免了符號(hào)位擴(kuò)展與zero拓展. 而且, 對(duì) loop index 使用 int/long 將減小 code 產(chǎn)生. 特別要指出, 在 thumb mode, stack pointer(SP) 被嚴(yán)格定義為 32-bit data types(因此更應(yīng)該使用 int/long).

       一個(gè)令人有興趣的簡(jiǎn)單實(shí)驗(yàn)?zāi)軌蜃C明, 所謂的”sign extension or zero extensize”帶來(lái)的額外代碼消耗. 在一份c的源文件中, 如果我們定義了 U8 global_data. 簡(jiǎn)單將其改為 U32 global_data. Then do rebuild all, we will find the code size decrease 4 bytes… ; ) 但是要提及的是, 我們的項(xiàng)目經(jīng)驗(yàn)說(shuō)明這個(gè)way往往還會(huì)帶來(lái)一個(gè)其他的效果: DATA size在這種情形下或略有增加.

 

2.       盡量避免使用帶符號(hào)位的數(shù)據(jù)類型.

 

3.       盡量避免 long(8-byte) 的定義.

 

4.       Bitfields 與 packed structures 將產(chǎn)生大而且慢的代碼.

對(duì)于 packed structures, 作者在相同的 blog 主頁(yè)發(fā)表了專題文章, 指出了選擇使用 packed structures, 仍然可以享受到盡可能小的 code size, 以及保持access speed的處理方式. 檢索作者的 blog, 或檢查全部文章列表, 將會(huì)發(fā)現(xiàn)該篇文章. 在我們的項(xiàng)目經(jīng)驗(yàn)中, 在 32k bytes 左右的 project 中, 我們獲得了額外的大約 2k bytes 的節(jié)省的 code size.

 

5.       盡量不要定義 float, double.

在一些運(yùn)算中, 我們常常將牽涉到如下步驟: 將float *10e(小數(shù)點(diǎn)后位數(shù)), 將float轉(zhuǎn)化為U32進(jìn)行運(yùn)算. 結(jié)果在/10e(相應(yīng)位數(shù)). 運(yùn)算精度在這里被降低了. 但這完全取決于我們的工作目標(biāo): 在不復(fù)雜的算法中, 避免了浮點(diǎn)運(yùn)算的使用(以上討論, 均假設(shè)我們的 mcu 不包含浮點(diǎn)運(yùn)算協(xié)處理器). Reference 也一再?gòu)?qiáng)調(diào)沒(méi)有math協(xié)處理器, 浮點(diǎn)數(shù)據(jù)類型效率低下.

 

6.       reference 指出, 盡量定義 local 變量. 減少 static 或 global 變量的定義, 這樣將幫助優(yōu)化的過(guò)程. 且local 變量盡量少使用 &. Reference 指出, 這種定義將放置變量到 memory 中, 而不能放置到處理器的 register 中(代碼會(huì)變大變慢). 另外也不能有助于優(yōu)化器進(jìn)行優(yōu)化.

 

7.       *(2的倍數(shù)), 或 /(2的倍數(shù)), 使用 “<<” 以及 “>>” 操作.

 

8.   應(yīng)保持?jǐn)?shù)據(jù)變量的type 定義的一致性, 在運(yùn)算中, 盡量減少類似 U32 -> U16 -> U32 的不必要的強(qiáng)制轉(zhuǎn)化過(guò)程.

 

9.   定義字符串為全局變量, 在 ram 富余的情況下, 這是一個(gè)利用 ram 來(lái)分擔(dān)降低 code size 的技巧.

構(gòu)建代碼的過(guò)程, 不僅僅是理性思維落實(shí)為真實(shí)世界邏輯的過(guò)程, 我們覺(jué)得, 也是和編譯器進(jìn)行交互的過(guò)程. 我們所作所為, 需要實(shí)現(xiàn)目的之邏輯, 我覺(jué)得也需要, "討好"編譯器, 讓它為我們的代碼, 生產(chǎn) size 和 speed 都得到優(yōu)化的job.

 

如何優(yōu)化C語(yǔ)言代碼

來(lái)源:互聯(lián)網(wǎng) 時(shí)間:2008-02-23
西部數(shù)碼-全國(guó)虛擬主機(jī)10強(qiáng)!40余項(xiàng)虛擬主機(jī)管理功能,全國(guó)領(lǐng)先!雙線多線虛擬主機(jī)南北訪問(wèn)暢通無(wú)阻!免費(fèi)贈(zèng)送企業(yè)郵局,.CN域名,自助建站480元起,免費(fèi)試用7天,滿意再付款! VPS主機(jī)租用266元/月(1G內(nèi)存)!
 1、選擇合適的算法和數(shù)據(jù)結(jié)構(gòu) 
  應(yīng)該熟悉算法語(yǔ)言,知道各種算法的優(yōu)缺點(diǎn),具體資料請(qǐng)參見(jiàn)相應(yīng)的參考資料,有很多電腦書籍上都有介紹。將比較慢的順序查找法用較快的二分查找或亂序查找法代替,插入排序或冒泡排序法用快速排序、合并排序或根排序代替,都能夠大大提高程式執(zhí)行的效率。.選擇一種合適的數(shù)據(jù)結(jié)構(gòu)也很重要,比如您在一堆隨機(jī)存放的數(shù)中使用了大量的插入和刪除指令,那使用鏈表要快得多。數(shù)組和指針語(yǔ)句具備十分密碼的關(guān)系,一般來(lái)說(shuō),指針比較靈活簡(jiǎn)潔,而數(shù)組則比較直觀,容易理解。對(duì)于大部分的編譯器,使用指針比使用數(shù)組生成的代碼更短,執(zhí)行效率更高。但是在Keil中則相反,使用數(shù)組比使用的指針生成的代碼更短。。 

  2。。。

  3、使用盡量小的數(shù)據(jù)類型
 
能夠使用字符型(char)定義的變量,就不要使用整型(int)變量來(lái)定義;能夠使用整型變量定義的變量就不要用長(zhǎng)整型(long int),能不使用浮點(diǎn)型(float)變量就不要使用浮點(diǎn)型變量。當(dāng)然,在定義變量后不要超過(guò)變量的作用范圍,假如超過(guò)變量的范圍賦值,C編譯器并不報(bào)錯(cuò),但程式運(yùn)行結(jié)果卻錯(cuò)了,而且這樣的錯(cuò)誤很難發(fā)現(xiàn)。 
在ICCAVR中,能夠在Options中設(shè)定使用printf參數(shù),盡量使用基本型參數(shù)(%c、 版權(quán)申明:本站文章均來(lái)自網(wǎng)絡(luò),如有侵權(quán),請(qǐng)聯(lián)系028-86262244-215,我們收到后立即刪除,謝謝! 
%d、%x、%X、%u和%s格式說(shuō)明符),少用長(zhǎng)整型參數(shù)(%ld、%lu、%lx和%lX格式說(shuō)明 符),至于浮點(diǎn)型的參數(shù)(%f)則盡量不要使用,其他C編譯器也相同。在其他條件不 變的情況下,使用%f參數(shù),會(huì)使生成的代碼的數(shù)量增加很多,執(zhí)行速度降低。 

  4、使用自加、自減指令 
  通常使用自加、自減指令和復(fù)合賦值表達(dá)式(如a-=1及a =1等)都能夠生成高質(zhì)量的
程式代碼,編譯器通常都能夠生成inc和dec之類的指令,而使用a=a 1或a=a-1之類
的指令,有很多C編譯器都會(huì)生成二到三個(gè)字節(jié)的指令。在AVR單片適用的ICCAVR、 GCCAVR、IAR等C編譯器以上幾種書寫方式生成的代碼是相同的,也能夠生成高質(zhì)量 的inc和dec之類的的代碼。 

  5、減少運(yùn)算的強(qiáng)度 
  能夠使用運(yùn)算量小但功能相同的表達(dá)式替換原來(lái)復(fù)雜的的表達(dá)式。如下: 

(1)、求余運(yùn)算。 
a=a%8; 
能夠改為: 
a=a&7; 
說(shuō)明:位操作只需一個(gè)指令周期即可完成,而大部分的C編譯器的“%”運(yùn)算均是調(diào) 用子程式來(lái)完成,代碼長(zhǎng)、執(zhí)行速度慢。通常,只需要是求2n方的余數(shù),均可使用 位操作的方法來(lái)代替。 

(2)、平方運(yùn)算 
a=pow(a,2.0); 
能夠改為: 
a=a*a; 
說(shuō)明:在有內(nèi)置硬件乘法器的單片機(jī)中(如51系列),乘法運(yùn)算比求平方運(yùn)算快得多,因?yàn)楦↑c(diǎn)數(shù)的求平方是通過(guò)調(diào)用子程式來(lái)實(shí)現(xiàn)的,在自帶硬件乘法器的AVR單片機(jī)中,如ATMega163中,乘法運(yùn)算只需2個(gè)時(shí)鐘周期就能夠完成。既使是在沒(méi)有內(nèi)置 硬件乘法器的AVR單片機(jī)中,乘法運(yùn)算的子程式比平方運(yùn)算的子程式代碼短,執(zhí)行速度快。 特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn),本站所提供的攝影照片,插畫,設(shè)計(jì)作品,如需使用,請(qǐng)與原作者聯(lián)系. 
假如是求3次方,如: 
a=pow(a,3.0); 
更改為: 
a=a*a*a; 
則效率的改善更明顯。 

(3)、用移位實(shí)現(xiàn)乘除法運(yùn)算 
a=a*4; 
b=b/4; 
能夠改為: 
a=a<<2; 
b=b>>2; 
說(shuō)明:通常假如需要乘以或除以2n,都能夠用移位的方法代替。在ICCAVR中,假如 乘以2n,都能夠生成左移的代碼,而乘以其他的整數(shù)或除以任何數(shù),均調(diào)用乘除法 子程式。用移位的方法得到代碼比調(diào)用乘除法子程式生成的代碼效率高。實(shí)際上, 只要是乘以或除以一個(gè)整數(shù),均能夠用移位的方法得到結(jié)果,如: 
a=a*9 
能夠改為: 
a=(a<<3) a 

  6、循環(huán) 

(1)、循環(huán)語(yǔ) 
對(duì)于一些無(wú)需循環(huán)變量參加運(yùn)算的任務(wù)能夠把他們放到循環(huán)外面,這里的任務(wù)包括表達(dá)式、函數(shù)的調(diào)用、指針運(yùn)算、數(shù)組訪問(wèn)等,應(yīng)該將沒(méi)有必要執(zhí)行多次的操作全部集合在一起,放到一個(gè)init的初始化程式中進(jìn)行。 

(2)、延時(shí)函數(shù): 
通常使用的延時(shí)函數(shù)均采用自加的形式: 
void delay (void) 

unsigned int i; 
for (i=0;i<1000;i ) 


將其改為自減延時(shí)函數(shù): 
void delay (void) 

unsigned int i; 
for (i=1000;i>0;i--) .. 


  兩個(gè)函數(shù)的延時(shí)效果相似,但幾乎任何的C編譯對(duì)后一種函數(shù)生成的代碼均比前一種代碼少1~3個(gè)字節(jié),因?yàn)閹缀跞魏蔚腗CU均有為0轉(zhuǎn)移的指令,采用后一種方式能夠生成這類指令。在使用while循環(huán)時(shí)也相同,使用自減指令控制循環(huán)會(huì)比使用自加指令控制循環(huán)生成的代碼更少1~3個(gè)字母。但是在循環(huán)中有通過(guò)循環(huán)變量“i”讀寫數(shù)組的指令時(shí),使用預(yù)減循環(huán)時(shí)有可能使數(shù)組超界,要引起注意。 

(3)while循環(huán)和do…while循環(huán) 
用while循環(huán)時(shí)有以下兩種循環(huán)形式: 
unsigned int i; 
i=0; 
while (i<1000) 

i ; 
//用戶程式 

或: 
unsigned int i; 
i=1000; 
do 
i--; 
//用戶程式 
while (i>0); 
在這兩種循環(huán)中,使用do…while循環(huán)編譯后生成的代碼的長(zhǎng)度短于while循環(huán)。 

  7、查表 
  在程式中一般不進(jìn)行很復(fù)雜的運(yùn)算,如浮點(diǎn)數(shù)的乘除及開(kāi)方等,連同一些復(fù)雜的數(shù)學(xué)模型的插補(bǔ)運(yùn)算,對(duì)這些即消耗時(shí)間又消費(fèi)資源的運(yùn)算,應(yīng)盡量使用查表的方式,并且將數(shù)據(jù)表置于程式存儲(chǔ)區(qū)。假如直接生成所需的表比較困難,也盡量在啟了,減少了程式執(zhí)行過(guò)程中重復(fù)計(jì)算的工作量。 

  8、其他 
  比如使用在線匯編及將字符串和一些常量保存在程式存儲(chǔ)器中,均有利于優(yōu)化
 
如何優(yōu)化C語(yǔ)言代碼(程序員必讀)------(1)

如何優(yōu)化C語(yǔ)言代碼(程序員必讀)[轉(zhuǎn)]http://www.diybl.com/ 2008-11-17  網(wǎng)絡(luò) 點(diǎn)擊:69  [ 評(píng)論 ]
文章搜索:     【點(diǎn)擊打包該文章】 被過(guò)濾廣告 
【本站開(kāi)通在線QQ討論群】

1、選擇合適的算法和數(shù)據(jù)結(jié)構(gòu)
      應(yīng)該熟悉算法語(yǔ)言,知道各種算法的優(yōu)缺點(diǎn),具體資料請(qǐng)參見(jiàn)相應(yīng)的參考資料,有很多計(jì)算機(jī)書籍上都有介紹。將比較慢的順序查找法用較快的二分查找或亂序查找法代替,插入排序或冒泡排序法用快速排序、合并排序或根排序代替,都可以大大提高程序執(zhí)行的效率。.選擇一種合適的數(shù)據(jù)結(jié)構(gòu)也很重要,比如你在一堆隨機(jī)存放的數(shù)中使用了大量的插入和刪除指令,那使用鏈表要快得多。數(shù)組與指針語(yǔ)句具有十分緊密的關(guān)系,一般來(lái)說(shuō),指針比較靈活簡(jiǎn)潔,而數(shù)組則比較直觀,容易理解。對(duì)于大部分的編譯器,使用指針比使用數(shù)組生成的代碼更短,執(zhí)行效率更高。但是在Keil中則相反,使用數(shù)組比使用的指針生成的代碼更短。。


3、使用盡量小的數(shù)據(jù)類型
      能夠使用字符型(char)定義的變量,就不要使用整型(int)變量來(lái)定義;能夠使用整型變量定義的變量就不要用長(zhǎng)整型(long int),能不使用浮點(diǎn)型(float)變量就不要使用浮點(diǎn)型變量。當(dāng)然,在定義變量后不要超過(guò)變量的作用范圍,如果超過(guò)變量的范圍賦值,C編譯器并不報(bào)錯(cuò),但程序運(yùn)行結(jié)果卻錯(cuò)了,而且這樣的錯(cuò)誤很難發(fā)現(xiàn)。
      在ICCAVR中,可以在Options中設(shè)定使用printf參數(shù),盡量使用基本型參數(shù)(%c、%d、%x、%X、%u和%s格式說(shuō)明符),少用長(zhǎng)整型參數(shù)(%ld、%lu、%lx和%lX格式說(shuō)明符),至于浮點(diǎn)型的參數(shù)(%f)則盡量不要使用,其它C編譯器也一樣。在其它條件不變的情況下,使用%f參數(shù),會(huì)使生成的代碼的數(shù)量增加很多,執(zhí)行速度降低。

4、使用自加、自減指令
      通常使用自加、自減指令和復(fù)合賦值表達(dá)式(如a-=1及a+=1等)都能夠生成高質(zhì)量的程序代碼,編譯器通常都能夠生成inc和dec之類的指令,而使用 a=a+1或a=a-1之類的指令,有很多C編譯器都會(huì)生成二到三個(gè)字節(jié)的指令。在AVR單片適用的ICCAVR、GCCAVR、IAR等C編譯器以上幾種書寫方式生成的代碼是一樣的,也能夠生成高質(zhì)量的inc和dec之類的的代碼。

5、減少運(yùn)算的強(qiáng)度
      可以使用運(yùn)算量小但功能相同的表達(dá)式替換原來(lái)復(fù)雜的的表達(dá)式。如下:
(1)、求余運(yùn)算。
        a=a%8;
可以改為:
        a=a&7;

說(shuō)明:位操作只需一個(gè)指令周期即可完成,而大部分的C編譯器的“%”運(yùn)算均是調(diào)用子程序來(lái)完成,代碼長(zhǎng)、執(zhí)行速度慢。通常,只要求是求2n方的余數(shù),均可使用位操作的方法來(lái)代替。

(2)、平方運(yùn)算
        a=pow(a,2.0);
可以改為:
        a=a*a;

說(shuō)明:在有內(nèi)置硬件乘法器的單片機(jī)中(如51系列),乘法運(yùn)算比求平方運(yùn)算快得多,因?yàn)楦↑c(diǎn)數(shù)的求平方是通過(guò)調(diào)用子程序來(lái)實(shí)現(xiàn)的,在自帶硬件乘法器的AVR 單片機(jī)中,如ATMega163中,乘法運(yùn)算只需2個(gè)時(shí)鐘周期就可以完成。既使是在沒(méi)有內(nèi)置硬件乘法器的AVR單片機(jī)中,乘法運(yùn)算的子程序比平方運(yùn)算的子程序代碼短,執(zhí)行速度快。

如果是求3次方,如:
        a=pow(a,3.0);
更改為:
        a=a*a*a;
則效率的改善更明顯。

(3)、用移位實(shí)現(xiàn)乘除法運(yùn)算
        a=a*4;
        b=b/4;
可以改為:
        a=a<<2;
        b=b>>2;

說(shuō)明:通常如果需要乘以或除以2n,都可以用移位的方法代替。在ICCAVR中,如果乘以2n,都可以生成左移的代碼,而乘以其它的整數(shù)或除以任何數(shù),均調(diào)用乘除法子程序。用移位的方法得到代碼比調(diào)用乘除法子程序生成的代碼效率高。實(shí)際上,只要是乘以或除以一個(gè)整數(shù),均可以用移位的方法得到結(jié)果,如:
        a=a*9
可以改為:
        a=(a<<3)+a

6、循環(huán)
(1)、循環(huán)語(yǔ)
      對(duì)于一些不需要循環(huán)變量參加運(yùn)算的任務(wù)可以把它們放到循環(huán)外面,這里的任務(wù)包括表達(dá)式、函數(shù)的調(diào)用、指針運(yùn)算、數(shù)組訪問(wèn)等,應(yīng)該將沒(méi)有必要執(zhí)行多次的操作全部集合在一起,放到一個(gè)init的初始化程序中進(jìn)行。

(2)、延時(shí)函數(shù):
通常使用的延時(shí)函數(shù)均采用自加的形式:
        void delay (void)
        {
unsigned int i;
        for (i=0;i<1000;i++)
        ;
        }
將其改為自減延時(shí)函數(shù):
        void delay (void)
        {
unsigned int i;
            for (i=1000;i>0;i--)
        ;
        }

      兩個(gè)函數(shù)的延時(shí)效果相似,但幾乎所有的C編譯對(duì)后一種函數(shù)生成的代碼均比前一種代碼少1~3個(gè)字節(jié),因?yàn)閹缀跛械腗CU均有為0轉(zhuǎn)移的指令,采用后一種方式能夠生成這類指令。在使用while循環(huán)時(shí)也一樣,使用自減指令控制循環(huán)會(huì)比使用自加指令控制循環(huán)生成的代碼更少1~3個(gè)字母。但是在循環(huán)中有通過(guò)循環(huán)變量“i”讀寫數(shù)組的指令時(shí),使用預(yù)減循環(huán)時(shí)有可能使數(shù)組超界,要引起注意。

(3)while循環(huán)和do…while循環(huán)
用while循環(huán)時(shí)有以下兩種循環(huán)形式:
unsigned int i;
        i=0;
        while (i<1000)
        {
            i++;
        //用戶程序
        }
或:
unsigned int i;
        i=1000;
        do
        i--;
        //用戶程序
        while (i>0);
      在這兩種循環(huán)中,使用do…while循環(huán)編譯后生成的代碼的長(zhǎng)度短于while循環(huán)。

7、查表
      在程序中一般不進(jìn)行非常復(fù)雜的運(yùn)算,如浮點(diǎn)數(shù)的乘除及開(kāi)方等,以及一些復(fù)雜的數(shù)學(xué)模型的插補(bǔ)運(yùn)算,對(duì)這些即消耗時(shí)間又消費(fèi)資源的運(yùn)算,應(yīng)盡量使用查表的方式,并且將數(shù)據(jù)表置于程序存儲(chǔ)區(qū)。如果直接生成所需的表比較困難,也盡量在啟了,減少了程序執(zhí)行過(guò)程中重復(fù)計(jì)算的工作量。

8、其它
比如使用在線匯編及將字符串和一些常量保存在程序存儲(chǔ)器中,均有利于優(yōu)化


嵌入式實(shí)時(shí)程序設(shè)計(jì)中C/C++代碼的優(yōu)化

1 引言

      計(jì)算機(jī)技術(shù)和信息技術(shù)的高速發(fā)展的今天,計(jì)算機(jī)和計(jì)算機(jī)技術(shù)大量應(yīng)用在人們的日常生活中,嵌入式計(jì)算機(jī)也得到了廣泛的應(yīng)用。 嵌入式計(jì)算機(jī)是指完成一種或多種特定功能的計(jì)算機(jī)系統(tǒng),是軟硬件的緊密結(jié)合體。具有軟件代碼小、高度自動(dòng)化、響應(yīng)速度快等特點(diǎn)。 特別適合于要求實(shí)時(shí)和多任務(wù)的應(yīng)用體系。嵌入式實(shí)時(shí)系統(tǒng)是目前蓬勃發(fā)展的行業(yè)之一。      但是,實(shí)時(shí)嵌入式系統(tǒng)的特點(diǎn)使得其軟件受時(shí)間和空間的嚴(yán)格限制,加上運(yùn)行環(huán)境復(fù)雜,使得嵌入式系統(tǒng)軟件的開(kāi)發(fā)變得異常困難。 為了設(shè)計(jì)一個(gè)滿足功能、性能和死線要求的系統(tǒng),為了開(kāi)發(fā)出安全可靠的高性能嵌入式系統(tǒng),開(kāi)發(fā)語(yǔ)言的選擇十分重要。 
2 嵌入式實(shí)時(shí)程序設(shè)計(jì)中語(yǔ)言的選擇

    
隨著嵌入式系統(tǒng)應(yīng)用范圍的不斷擴(kuò)大和嵌入式實(shí)時(shí)操作系統(tǒng)RTOS(Real Time Operating System)的廣泛使用,高級(jí)語(yǔ)言編程已是嵌入式系統(tǒng)設(shè)計(jì)的必然趨勢(shì)。因?yàn)閰R編語(yǔ)言和具體的微處理器的硬件結(jié)構(gòu)密切相關(guān),移植性較差,既不宜在復(fù)雜系統(tǒng)中使用,又不便于實(shí)現(xiàn)軟件重用;而高級(jí)語(yǔ)言具有良好的通用性和豐富的軟件支持,便于推廣、易于維護(hù),因此高級(jí)語(yǔ)言編程具有許多優(yōu)勢(shì)。目前,在嵌入式系統(tǒng)開(kāi)發(fā)過(guò)程中使用的語(yǔ)言種類很多,但僅有少數(shù)幾種語(yǔ)言得到了比較廣泛的應(yīng)用。其中C和C++是應(yīng)用最廣泛的。C++在支持現(xiàn)代軟件工程、 OOP(Object Oriented Programming,面向?qū)ο蟮某绦蛟O(shè)計(jì))、結(jié)構(gòu)化等方面對(duì)C進(jìn)行了卓有成效的改進(jìn),但在程序代碼容量、執(zhí)行速度、程序復(fù)雜程度等方面比C語(yǔ)言程序性能差一些。由于C語(yǔ)言既有低級(jí)語(yǔ)言的直接控制硬件的能力,又有高級(jí)語(yǔ)言的靈活性,是目前在嵌入式系統(tǒng)中應(yīng)用最廣泛的編程語(yǔ)言。隨著網(wǎng)絡(luò)技術(shù)和嵌入式技術(shù)的不斷發(fā)展,Java的應(yīng)用也得到廣泛應(yīng)用。

3 C/C++代碼在實(shí)時(shí)程序設(shè)計(jì)中的優(yōu)化

    
雖然使軟件正確是一個(gè)工程合乎邏輯的最后一個(gè)步驟,但是在嵌入式的系統(tǒng)開(kāi)發(fā)中,情況并不總是這樣的。出于對(duì)低價(jià)產(chǎn)品的需求, 硬件的設(shè)計(jì)者需要提供剛好足夠的存儲(chǔ)器和完成工作的處理能力。所以在嵌入式軟件設(shè)計(jì)的最后一個(gè)階段則變成了對(duì)代碼的優(yōu)化。   

現(xiàn)代的C和C++編譯器都提供了一定程度上的代碼優(yōu)化。然而,大部分由編譯器執(zhí)行的優(yōu)化僅涉及執(zhí)行速度和代碼大小的一個(gè)平衡。你的程序能夠變得更快或者更小,但是不可能又變快又變小。經(jīng)過(guò)本人在嵌入式系統(tǒng)設(shè)計(jì)和實(shí)現(xiàn)過(guò)程中實(shí)踐,下面介紹幾種簡(jiǎn)單且行之有效的C/C++代碼的優(yōu)化方法。

      (1) Inline函數(shù)

      在C++中,關(guān)鍵字Inline可以被加入到任何函數(shù)的聲明中。這個(gè)關(guān)鍵字請(qǐng)求編譯器用函數(shù)內(nèi)部的代碼替換所有對(duì)于指出的函數(shù)的調(diào)用。這樣做在兩個(gè)方面快于函數(shù)調(diào)用。這樣做在兩個(gè)方面快于函數(shù)調(diào)用:第一,省去了調(diào)用指令需要的執(zhí)行時(shí)間;第二,省去了傳遞變?cè)蛡鬟f過(guò)程需要的時(shí)間。但是使用這種方法在優(yōu)化程序速度的同時(shí),程序長(zhǎng)度變大了,因此需要更多的ROM。使用這種優(yōu)化在Inline函數(shù)頻繁調(diào)用并且只包含幾行代碼的時(shí)候是最有效的。 
      (2)用指針代替數(shù)組

      在許多種情況下,可以用指針運(yùn)算代替數(shù)組索引,這樣做常常能產(chǎn)生又快又短的代碼。與數(shù)組索引相比,指針一般能使代碼速度更快,占用空間更少。使用多維數(shù)組時(shí)差異更明顯。下面的代碼作用是相同的,但是效率不一樣。 
      數(shù)組索引                  指針運(yùn)算 
      For(;;){                  p=array 
      A=array[t++];            for(;;){ 
                                  a=*(p++); 
      ......                      ...... 
      }                        }

      指針?lè)椒ǖ膬?yōu)點(diǎn)是,array的地址每次裝入地址p后,在每次循環(huán)中只需對(duì)p增量操作。在數(shù)組索引方法中,每次循環(huán)中都必須進(jìn)行基于t值求數(shù)組下標(biāo)的復(fù)雜運(yùn)算。 
      (3)不定義不使用的返回值

      function函數(shù)定義并不知道函數(shù)返回值是否被使用,假如返回值從來(lái)不會(huì)被用到,應(yīng)該使用void來(lái)明確聲明函數(shù)不返回任何值。

      (4)手動(dòng)編寫匯編

      在嵌入式軟件開(kāi)發(fā)中,一些軟件模塊最好用匯編語(yǔ)言來(lái)寫,這可以使程序更加有效。雖然C/C++編譯器對(duì)代碼進(jìn)行了優(yōu)化,但是適當(dāng)?shù)氖褂脙?nèi)聯(lián)匯編指令可以有效的提高整個(gè)系統(tǒng)運(yùn)行的效率。 
      (5)使用寄存器變量

      在聲明局部變量的時(shí)候可以使用register關(guān)鍵字。這就使得編譯器把變量放入一個(gè)多用途的寄存器中,而不是在堆棧中,合理使用這種方法可以提高執(zhí)行速度。函數(shù)調(diào)用越是頻繁,越是可能提高代碼的速度。 
      (6)使用增量和減量操作符

      在使用到加一和減一操作時(shí)盡量使用增量和減量操作符,因?yàn)樵隽糠Z(yǔ)句比賦值語(yǔ)句更快,原因在于對(duì)大多數(shù)CPU來(lái)說(shuō),對(duì)內(nèi)存字的增、 減量操作不必明顯地使用取內(nèi)存和寫內(nèi)存的指令,比如下面這條語(yǔ)句: 
      x=x+1; 
      模仿大多數(shù)微機(jī)匯編語(yǔ)言為例,產(chǎn)生的代碼類似于: 
      move A,x        ;把x從內(nèi)存取出存入累加器A 
      add A,1        ;累加器A加1 
      store x        ;把新值存回x

      如果使用增量操作符,生成的代碼如下: 
      incr x          ;x加1 
      顯然,不用取指令和存指令,增、減量操作執(zhí)行的速度加快,同時(shí)長(zhǎng)度也縮短了。

      (7)減少函數(shù)調(diào)用參數(shù)

      使用全局變量比函數(shù)傳遞參數(shù)更加有效率。這樣做去除了函數(shù)調(diào)用參數(shù)入棧和函數(shù)完成后參數(shù)出棧所需要的時(shí)間。然而決定使用全局變量會(huì)影響程序的模塊化和重入,故要慎重使用。 
      (8)Switch語(yǔ)句中根據(jù)發(fā)生頻率來(lái)進(jìn)行case排序

      switch語(yǔ)句是一個(gè)普通的編程技術(shù),編譯器會(huì)產(chǎn)生if-else-if的嵌套代碼,并按照順序進(jìn)行比較,發(fā)現(xiàn)匹配時(shí),就跳轉(zhuǎn)到滿足條件的語(yǔ)句執(zhí)行。使用時(shí)需要注意。每一個(gè)由機(jī)器語(yǔ)言實(shí)現(xiàn)的測(cè)試和跳轉(zhuǎn)僅僅是為了決定下一步要做什么,就把寶貴的處理器時(shí)間耗盡。為了提高速度,沒(méi)法把具體的情況按照它們發(fā)生的相對(duì)頻率排序。換句話說(shuō),把最可能發(fā)生的情況放在第一位,最不可能的情況放在最后。 
      (9)將大的switch語(yǔ)句轉(zhuǎn)為嵌套switch語(yǔ)句

      當(dāng)switch語(yǔ)句中的case標(biāo)號(hào)很多時(shí),為了減少比較的次數(shù),明智的做法是把大switch語(yǔ)句轉(zhuǎn)為嵌套switch語(yǔ)句。把發(fā)生頻率高的case 標(biāo)號(hào)放在一個(gè)switch語(yǔ)句中,并且是嵌套switch語(yǔ)句的最外層,發(fā)生相對(duì)頻率相對(duì)低的case標(biāo)號(hào)放在另一個(gè)switch語(yǔ)句中。比如,下面的程序段把相對(duì)發(fā)生頻率低的情況放在缺省的case標(biāo)號(hào)內(nèi)。          pMsg=ReceiveMessage(); 
          switch (pMsg->type) 
          { 
          case FREQUENT_MSG1: 
          handleFrequentMsg(); 
          break; 
          case FREQUENT_MSG2: 
          handleFrequentMsg2(); 
          break; 
          ...... 
          case FREQUENT_MSGn: 
          handleFrequentMsgn(); 
          break; 
          default:                        //嵌套部分用來(lái)處理不經(jīng)常發(fā)生的消息 
          switch (pMsg->type) 
          { 
          case INFREQUENT_MSG1: 
          handleInfrequentMsg1(); 
          break; 
          case INFREQUENT_MSG2: 
          handleInfrequentMsg

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
手把手教你如何優(yōu)化C語(yǔ)言程序
優(yōu)化C語(yǔ)言代碼(程序員必讀)|,while,整型,運(yùn)算,指令,循環(huán),參數(shù),程序
學(xué)習(xí)單片機(jī)八大步驟
SIMD 編程的優(yōu)勢(shì)
C64x的軟件優(yōu)化方法 - Polluxa.com -
c代碼優(yōu)化方案 - quanming1119的專欄
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服