<var id="fnfpo"><source id="fnfpo"></source></var>
<rp id="fnfpo"></rp>

<em id="fnfpo"><object id="fnfpo"><input id="fnfpo"></input></object></em>
<em id="fnfpo"><acronym id="fnfpo"></acronym></em>
  • <th id="fnfpo"><track id="fnfpo"></track></th>
  • <progress id="fnfpo"><track id="fnfpo"></track></progress>
  • <tbody id="fnfpo"><pre id="fnfpo"></pre></tbody>

  • x
    x

    嵌入式系統編程中的代碼優化

    發布時間:2010-9-20 12:33    發布者:eetech
    關鍵詞: 編程 , 代碼 , 嵌入式系統
    在當前計算機技術高度發展的今天,嵌入式系統已經廣泛地應用于工業控制、信息家電、辦公自動化、移動通信、儀器儀表、醫療電子以及國防等領域。隨著國內外各種嵌入式產品的進一步開發和推廣,嵌入式技術越來越和人們的生活緊密結合。

    嵌入式系統一般指非PC系統,通常完成一種或多種特定的計算機功能。它是以應用為中心,軟硬件可裁減的,適應應用系統對功能,可靠性,成本,體積,功耗等綜合性要求的專用計算機系統。簡單的說類似于PC中的BIOS的工作方式,具有軟件代碼小、高度自動化、響應速度快等特點。 特別適合于要求實時和多任務的應用體系。嵌入式實時系統是目前蓬勃發展的行業之一。但是,實時嵌入式系統的特點使得其軟件受時間和空間的嚴格限制,加上運行環境復雜,使得嵌入式系統軟件的開發變得異常困難。 為了設計一個滿足功能、性能和時間要求的安全可靠的高性能嵌入式系統,編程語言的選擇十分重要。

    1、嵌入式系統中編程語言的選擇

    因為匯編語言編寫的代碼難懂,從而不好維護和難于調試,且只能針對特定的體系結構和處理器移植性差, 所以既不宜在復雜系統中使用,又不便于實現軟件重用;而高級語言具有良好的通用性和豐富的軟件支持,可移植性好、易于維護,因此高級語言編程具有許多優勢。隨著嵌入式系統應用范圍的不斷擴大和嵌入式實時操作系統RTOS(Real Time Operating System)的廣泛使用,高級語言編程已是嵌入式系統設計的必然趨勢。但是 不排除一些軟件模塊仍用匯編語言來寫,這可以使程序更加有效。雖然C/C++編譯器對代碼進行了優化,但是適當的使用內聯匯編指令可以有效的提高整個系統運行的效率。 目前,在嵌入式系統開發過程中使用的語言種類很多,但僅有少數幾種語言得到了比較廣泛的應用。其中C和C++是應用最廣泛的。C++在支持現代軟件工程、 OOP(Object Oriented Programming,面向對象的程序設計)、結構化等方面對C進行了卓有成效的改進,但在程序代碼容量、執行速度、 程序復雜程度等方面比C語言程序性能差一些。由于C語言既有低級語言的直接控制硬件的能力,又有高級語言的靈活性,是目前在嵌入式系統中應用最廣泛的編程語言。隨著網絡技術和嵌入式技術的不斷發展,Java的應用也得到廣泛應用。

    2、實時程序設計中代碼的優化

    在嵌入式的系統開發中,出于對低價產品的需求, 硬件的設計者需要提供剛好足夠的存儲器和完成工作的處理能力。所以在嵌入式軟件設計的最后一個階段則變成了對代碼的優化。

    代碼優化的目標是體積小和速度快,可以從算法、數據和指令流三方面來考慮。

    算法優化

    大多數情況下,速度同內存(或者是性能,比如說壓縮性能)是不可兼得的。目前程序加速的常用算法一個大方面就是利用查表來避免計算(比如在jpg有huffman碼表,在YUV到RGB變換也有變換表)這樣原來的復雜計算現在僅僅查表就可以了,雖然浪費了內存,不過速度顯著提升。此外在編寫程序時還要注意提高效率,例如:

    Switch語句中根據發生頻率來進行case排序

    switch語句是一個普通的編程技術,編譯器會產生if-else-if的嵌套代碼,并按照順序進行比較,發現匹配時,就跳轉到滿足條件的語句執行。使用時需要注意。每一個由機器語言實現的測試和跳轉僅僅是為了決定下一步要做什么,就把寶貴的處理器時間耗盡。為了提高速度,設法根據具體的情況按照它們發生的相對頻率排序。換句話說,把最可能發生的情況放在第一位,最不可能的情況放在最后。

    將大的switch語句轉為嵌套switch語句

    當switch語句中的case標號很多時,為了減少比較的次數,明智的做法是把大switch語句轉為嵌套switch語句。把發生頻率高的case 標號放在一個switch語句中,并且是嵌套switch語句的最外層,發生相對頻率相對低的case標號放在另一個switch語句中。 如果switch中每一種情況下都有很多的工作要做,那么把整個switch語句用一個指向函數指針的表來替換會更加有效。

    用指針代替數組

    在許多種情況下,可以用指針運算代替數組索引,這樣做常常能產生又快又短的代碼。與數組索引相比,指針一般能使代碼速度更快,占用空間更少。使用多維數組時差異更明顯。下面的代碼作用是相同的,但是效率不一樣。

    數組索引指針運算

    For(;;){ p="array"

    A=array[r++]; for(;;){

    a=*(p++);

    ...... ......

    } }

    指針方法的優點是,array的地址每次裝入地址p后,在每次循環中只需對p增量操作。在數組索引方法中,每次循環中都必須進行基于r值求數組下標的復雜運算。

    使用宏函數而不是函數。例如:

    #define bwMCDR2_ADDRESS 4

    #define bsMCDR2_ADDRESS 17

    #define bmMCDR2_ADDRESS BIT_MASK(MCDR2_ADDRESS)

    #define BIT_MASK(__bf) (((1U << (bw ## __bf)) - 1) << (bs ## __bf))

    #define SET_BITS(__dst, __bf, __val) ((__dst) = ((__dst) & "(BIT_MASK(__bf))) | (((__val) << (bs ## __bf)) & (BIT_MASK(__bf))))

    SET_BITS(MCDR2, MCDR2_ADDRESS, RegisterNumber);

    函數和宏函數的區別就在于,宏函數占用了大量的空間,而函數占用了時間。函數調用是要使用系統的棧來保存數據的,如果編譯器里有棧檢查選項,一般在函數的頭會嵌入一些匯編語句對當前棧進行檢查;同時,CPU也要在函數調用時保存和恢復當前的現場,進行壓棧和彈棧操作,所以,函數調用需要一些CPU時間。而宏函數不存在這個問題。宏函數僅僅作為預先寫好的代碼嵌入到當前程序,不會產生函數調用,所以僅僅是占用了空間,在頻繁調用同一個宏函數的時候,該現象尤其突出。

    Data optimization數據優化

    比算法優化層低一級的是數據優化層,我們可以通過改變算法使用的數據類型來優化算法。主要的目的是使處理的數據和目標結構的特性相一致。這項優化不需要大量的代碼重寫,并獨立于算法優化的執行而執行.例如:

    確定浮點型變量和表達式是 float 型

    為了讓編譯器產生更好的代碼,必須確定浮點型變量和表達式是 float 型的。要特別注意的是,以 ";F"; 或 ";f"; 為后綴(比如:2.718f)的浮點常量才是 float 型,否則默認是 double 型。為了避免 float 型參數自動轉化為 double,請在函數聲明時使用 float。

    使用32位的數據類型

    編譯器有很多種,但它們都包含的典型的32位類型是:int,signed,signed int,unsigned,unsigned int,long,signed long,long int,signed long int,unsigned long,unsigned long int。盡量使用32位的數據類型,因為它們比16位的數據甚至8位的數據更有效率。

    明智使用有符號整型變量

    在很多情況下,你需要考慮整型變量是有符號還是無符號類型的。在許多地方,考慮是否使用有符號的變量是必要的。在一些情況下,有符號的運算比較快;但在一些情況下卻相反。 比如:整型到浮點轉化時,使用大于16位的有符號整型比較快。因為x86構架中提供了從有符號整型轉化到浮點型的指令,但沒有提供從無符號整型轉化到浮點的指令。在整數運算中計算商和余數時,使用無符號類型比較快。

    Instruction flow optimization指令流優化

    第三層優化的目標是低級指令流。比較常見的技術是循環合并(loop merging),循環展開(unrolling),軟件流水(software pipelining)。

    循環合并

    如果兩個循環計數差不多、循環執行互不相同的操作,可以把它們合并在一起組成一個循環。當兩個循環的負荷都不滿時,這是非常有用的。

    循環展開

    循環展開就是把循環計數小的循環展開,成為非循環形式的串行程序,或者把循環計數大的循環部分展開,減少循環迭代次數,這樣可以節省了用于循環設置、初始化、增加和校對循環計數器的時間。大多數編譯器可以自動完成這項工作,手工編譯會出現錯例如:

    for( int i = 0; i < 3; i++ ) array[ i] = i;

    邏輯上等同于:

    array[0] = 0; array = 1, array = 2;

    軟件流水

    軟件流水是用來安排循環指令,使這個循環多次迭代并行執行的一種技術。在嵌套循環中,編譯器僅對最里面的循環執行軟件流水,因此對執行周期很少的內循環作循環展開,外循環進行軟件流水,這樣可以改進C代碼并行執行的性能。使用軟件流水還應當注意:盡管軟件流水循環可以包含內聯函數,但是不能包含函數調用;在循環中不可以有條件終止指令;在循環體中不可以修改循環控制變量。

    3、總結語

    現代的C和C++編譯器都提供了一定程度上的代碼優化。然而,大部分由編譯器執行的優化僅涉及執行速度和代碼大小的一個平衡。你的程序能夠變得更快或者更小,但是不可能又變快又變小。上面介紹的方法主要是為了提高代碼的效率。但是事實上,在使用這些技術提高代碼運行速度的同時會相應的產生一些負面的影響,比如增加代碼的大小、降低程序可讀性等。不過你可以讓C/C++編 譯器來進行減少代碼大小的優化,而手動利用編程來減少代碼的執行時間。在嵌入式程序設計中合理地使用這幾種技術有時會達到很好 的優化效果。
    本文地址:http://www.portaltwn.com/thread-28245-1-1.html     【打印本頁】

    本站部分文章為轉載或網友發布,目的在于傳遞和分享信息,并不代表本網贊同其觀點和對其真實性負責;文章版權歸原作者及原出處所有,如涉及作品內容、版權和其它問題,我們將根據著作權人的要求,第一時間更正或刪除。
    hawkfier 發表于 2010-9-21 09:16:22
    學習啦~
    您需要登錄后才可以發表評論 登錄 | 立即注冊

    廠商推薦

    • Microchip視頻專區
    • EtherCAT®和Microchip LAN925x從站控制器介紹培訓教程
    • MPLAB®模擬設計器——在線電源解決方案,加速設計
    • 讓您的模擬設計靈感,化為觸手可及的現實
    • 深度體驗Microchip自動輔助駕駛應用方案——2025巡展開啟報名!
    • 貿澤電子(Mouser)專區

    相關視頻

    關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
    電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
    快速回復 返回頂部 返回列表
    精品一区二区三区自拍图片区_国产成人亚洲精品_亚洲Va欧美va国产综合888_久久亚洲国产精品五月天婷