<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-144  評論-80  文章-1  trackbacks-0

    C語言嵌入式系統編程修煉之六:性能優化

    作者:宋寶華   更新日期:2005-07-22

    使用宏定義

      在C語言中,宏是產生內嵌代碼的唯一方法。對于嵌入式系統而言,為了能達到性能要求,宏是一種很好的代替函數的方法。

      寫一個"標準"宏MIN ,這個宏輸入兩個參數并返回較小的一個:

      錯誤做法:

    #define MIN(A,B)  ( A <= B ? A : B )

      正確做法:

    #define MIN(A,B) ((A)<= (B) ? (A) : (B) )

      對于宏,我們需要知道三點:

      (1)宏定義"像"函數;

      (2)宏定義不是函數,因而需要括上所有"參數";

      (3)宏定義可能產生副作用。

      下面的代碼:

    least = MIN(*p++, b);

      將被替換為:

    ( (*p++) <= (b) ?(*p++):(b) )

      發生的事情無法預料。

      因而不要給宏定義傳入有副作用的"參數"。

      使用寄存器變量

       當對一個變量頻繁被讀寫時,需要反復訪問內存,從而花費大量的存取時間。為此,C語言提供了一種變量,即寄存器變量。這種變量存放在CPU的寄存器中, 使用時,不需要訪問內存,而直接從寄存器中讀寫,從而提高效率。寄存器變量的說明符是register。對于循環次數較多的循環控制變量及循環體內反復使 用的變量均可定義為寄存器變量,而循環計數是應用寄存器變量的最好候選者。

      (1) 只有局部自動變量和形參才可以定義為寄存器變量。因為寄存器變量屬于動態存儲方式,凡需要采用靜態存儲方式的量都不能定義為寄存器變量,包括:模塊間全局變量、模塊內全局變量、局部static變量;

      (2) register是一個"建議"型關鍵字,意指程序建議該變量放在寄存器中,但最終該變量可能因為條件不滿足并未成為寄存器變量,而是被放在了存儲器中,但編譯器中并不報錯(在C++語言中有另一個"建議"型關鍵字:inline)。

      下面是一個采用寄存器變量的例子:

    /* 求1+2+3+….+n的值 */
    WORD Addition(BYTE n)
    {
     register i,s=0;
     for(i=1;i<=n;i++)
     {
      s=s+i;
     }
     return s;
    }

      本程序循環n次,i和s都被頻繁使用,因此可定義為寄存器變量。

      內嵌匯編

      程序中對時間要求苛刻的部分可以用內嵌匯編來重寫,以帶來速度上的顯著提高。但是,開發和測試匯編代碼是一件辛苦的工作,它將花費更長的時間,因而要慎重選擇要用匯編的部分。

      在程序中,存在一個80-20原則,即20%的程序消耗了80%的運行時間,因而我們要改進效率,最主要是考慮改進那20%的代碼。

      嵌入式C程序中主要使用在線匯編,即在C程序中直接插入_asm{ }內嵌匯編語句:

    /* 把兩個輸入參數的值相加,結果存放到另外一個全局變量中 */
    int result;
    void Add(long a, long *b)
    {
     _asm
     {
      MOV AX, a
      MOV BX, b
      ADD AX, [BX]
      MOV result, AX
     }
    }

      利用硬件特性

      首先要明白CPU對各種存儲器的訪問速度,基本上是:

    CPU內部RAM > 外部同步RAM > 外部異步RAM > FLASH/ROM

      對于程序代碼,已經被燒錄在FLASH或ROM中,我們可以讓CPU直接從其中讀取代碼執行,但通常這不是一個好辦法,我們最好在系統啟動后將FLASH或ROM中的目標代碼拷貝入RAM中后再執行以提高取指令速度;

      對于UART等設備,其內部有一定容量的接收BUFFER,我們應盡量在BUFFER被占滿后再向CPU提出中斷。例如計算機終端在向目標機通過RS-232傳遞數據時,不宜設置UART只接收到一個BYTE就向CPU提中斷,從而無謂浪費中斷處理時間;

       如果對某設備能采取DMA方式讀取,就采用DMA讀取,DMA讀取方式在讀取目標中包含的存儲信息較大時效率較高,其數據傳輸的基本單位是塊,而所傳輸 的數據是從設備直接送入內存的(或者相反)。DMA方式較之中斷驅動方式,減少了CPU 對外設的干預,進一步提高了CPU與外設的并行操作程度。

      活用位操作

      使用C語言的位操作可以減少除法和取模的運算。在計算機程序中數據的位是可以操作的最小數據單位,理論上可以用"位運算"來完成所有的運算和操作,因而,靈活的位操作可以有效地提高程序運行的效率。舉例如下:

    /* 方法1 */
    int i,j;
    i = 879 / 16;
    j = 562 % 32;
    /* 方法2 */
    int i,j;
    i = 879 >> 4;
    j = 562 - (562 >> 5 << 5);

      對于以2的指數次方為"*"、"/"或"%"因子的數學運算,轉化為移位運算"<< >>"通常可以提高算法效率。因為乘除運算指令周期通常比移位運算大。

       C語言位運算除了可以提高運算效率外,在嵌入式系統的編程中,它的另一個最典型的應用,而且十分廣泛地正在被使用著的是位間的與(&)、或 (|)、非(~)操作,這跟嵌入式系統的編程特點有很大關系。我們通常要對硬件寄存器進行位設置,譬如,我們通過將AM186ER型80186處理器的中 斷屏蔽控制寄存器的第低6位設置為0(開中斷2),最通用的做法是:

    #define INT_I2_MASK 0x0040
    wTemp = inword(INT_MASK);
    outword(INT_MASK, wTemp &~INT_I2_MASK);

      而將該位設置為1的做法是:

    #define INT_I2_MASK 0x0040
    wTemp = inword(INT_MASK);
    outword(INT_MASK, wTemp | INT_I2_MASK);

      判斷該位是否為1的做法是:

    #define INT_I2_MASK 0x0040
    wTemp = inword(INT_MASK);
    if(wTemp & INT_I2_MASK)
    {
    … /* 該位為1 */
    }

      上述方法在嵌入式系統的編程中是非常常見的,我們需要牢固掌握。

      總結

      在性能優化方面永遠注意80-20準備,不要優化程序中開銷不大的那80%,這是勞而無功的。

       宏定義是C語言中實現類似函數功能而又不具函數調用和返回開銷的較好方法,但宏在本質上不是函數,因而要防止宏展開后出現不可預料的結果,對宏的定義和 使用要慎而處之。很遺憾,標準C至今沒有包括C++中inline函數的功能,inline函數兼具無調用開銷和安全的優點。

      使用寄存器變量、內嵌匯編和活用位操作也是提高程序效率的有效方法。

      除了編程上的技巧外,為提高系統的運行效率,我們通常也需要最大可能地利用各種硬件設備自身的特點來減小其運轉開銷,例如減小中斷次數、利用DMA傳輸方式等。
    posted on 2005-09-21 17:35 小力力力 閱讀(2211) 評論(3)  編輯  收藏 所屬分類: C/C++

    評論:
    # re: C語言嵌入式系統編程修煉之六:性能優化 2006-01-14 15:20 |
    我現在是一個計算機專業 的學生~對C語言 還是有一定的了解~我知道C嵌入式  是一個很好的學科  它也許是以后程序的精華  我現在能開始 學C嵌入了嘛?
      回復  更多評論
      
    # re: C語言嵌入式系統編程修煉之六:性能優化 2006-01-14 15:21 |
    我是說 在學C嵌入之前 應該掌握 C語言的 那些重點知識  回復  更多評論
      
    # re: C語言嵌入式系統編程修煉之六:性能優化 2007-04-29 17:06 | fanyujin
    謝謝作者  回復  更多評論
      
    主站蜘蛛池模板: 亚洲精品视频久久| 中文字幕一精品亚洲无线一区| 亚洲精品美女久久久久99| 免费人成大片在线观看播放| 免费看黄视频网站| 亚洲依依成人精品| 亚洲网站免费观看| 久久精品国产亚洲av麻豆小说| 人妻免费一区二区三区最新| 亚洲一级黄色视频| 青柠影视在线观看免费高清| 亚洲欧洲自拍拍偷午夜色无码| 一个人看www免费高清字幕| 亚洲av再在线观看| 中国毛片免费观看| 久久亚洲精精品中文字幕| 男的把j放进女人下面视频免费| 亚洲精品无码久久千人斩| 亚洲精品一卡2卡3卡四卡乱码| 国产三级在线观看免费| 亚洲欧美第一成人网站7777| 国产无遮挡吃胸膜奶免费看视频 | 特级无码毛片免费视频| 亚洲欧洲日本在线| 国产激情免费视频在线观看 | 亚洲网址在线观看| 成年男女免费视频网站| 爱情岛论坛亚洲品质自拍视频网站 | 色天使色婷婷在线影院亚洲| 亚洲免费日韩无码系列| 精品免费tv久久久久久久| 亚洲国产精品成人综合久久久| 在线观看无码的免费网站| 三年片在线观看免费观看大全中国| 国内精品久久久久久久亚洲 | 日韩精品内射视频免费观看| 国产成人精品日本亚洲专区6| 亚洲午夜无码久久久久| 在人线av无码免费高潮喷水| 黄色网页在线免费观看| 亚洲国产精品网站在线播放 |