如何在ARM平臺上開發(fā)低功耗的軟件系統(tǒng)
![](http://uphotos.eepw.com.cn/fetch/20130729/148887_2_0.jpg)
圖4:緩存的能量優(yōu)勢
圖4摘自普林斯頓(Brooks,2000)一份論文,顯示了針對某簡單應用基準的三套數據。針對不同的緩存大小,這些條塊分別代表性能IP C(單位周期指令數)、功耗和功耗時間積(ED P)??偟膩碚f,性能會隨著緩存大小的增加而提升。但是,系統(tǒng)的功耗也會增加,因為增大緩存單元會相應增加功耗。功耗時間積允許我們在性能和緩存大小之間取得平衡。在這個例子里,存在一個最佳點,即緩存大小為64k時,此時的功耗時間積最小。
最大限度減少數據內存存取
A RM架構的一個特性是其常量是不確定的,特別是,不可能用單條指令把一個任意32位常量放到一個寄存器中。實際上,所有內存存取必須按寄存器中的地址操作,這就意味著程序需要把這些地址和其他常量頻繁地放到寄存器中,而這一點很難做到。解決此問題的標準方法是把常量作為文字數據嵌入到代碼段中,在運行時使用PC相關的加載進行加載。
因此,這種最大限度減少常量影響的方法很實用。確保在編譯時這些常量是已知的,如果可能,最好能把這些常量嵌入到單條ARM指令中。為了存取全局變量,盡可能減少加載基址指針的需求。這就需要確保全局變量在運行時都在內存中,這樣才能使用單個指針存取多個變量。實現這個目標最簡單的方式是將全局變量放到一個結構中。
盡管A R M的堆棧訪問相對高效(堆棧訪問可較好地加載和存儲多條指令),但是程序員還可以通過很多方式來減少堆棧訪問:減少活動變量、避免占用本地變量地址、可能時充分利用尾部調用優(yōu)化、將傳遞到函數的參數數量減少到四個以下、允許編譯器主動內聯函數等。
遞歸情形和避免遞歸情形的做法更加復雜。通常編譯器可以對歸函數很好地進行尾部優(yōu)化。實際上將所有數據存儲到堆棧中可以比其他做法獲得更好的局部性?;蛟S建議可能最好表達為“除非其他做法讓數據局部性更糟或您確信編譯器可以對遞歸調用進行尾部優(yōu)化,否則不要使用遞歸算法”。應編寫異常處理程序,增加尾部連鎖的機會,進而避免堆棧環(huán)境內不必要的保存和恢復。
現在我們把注意力轉到這個問題的第二頭大象,即指令執(zhí)行。
最大限度減少指令數目
事實上,減少指令執(zhí)行次數本質上與性能優(yōu)化是相同的,執(zhí)行的指令數越少,能耗就越低。另外,還要增加一些明顯的指針。
首先,正確地配置工具。在編譯器和鏈接器完全了解目標平臺,甚至無法實施一些基本的優(yōu)化。
編寫代碼時要保持敏銳,才能避免不必要的操作。對于A R M架構,32位數據類型是高效的:一般8位和16位數據類型,盡管占用的存儲空間較少,但是處理效率也較低。在v6和v7架構中,打包和接包指令以及S IM D操作一定程序上對此有些幫助,但是要注意,在主程序中無法從C訪問這些指令。
編寫循環(huán)時要當心
可以按照以下一些簡單的規(guī)則來編寫循環(huán):使用無符號的整數計數器,向下倒數,并把是否等于零作為終止條件。這可以讓循環(huán)更短,速度更快,使用的寄存器更少。還要記住,要采用矢量化來編寫循環(huán)。即使在嘗試展開和矢量化最簡單的循環(huán)時,有關控制結構和數據聲明的一些簡單規(guī)則都可以讓編譯器的作業(yè)變得更簡單。
![](http://uphotos.eepw.com.cn/fetch/20130729/148887_2_1.jpg)
圖5:循環(huán)展開
圖5顯示了與一個特定循環(huán)優(yōu)化有關的一些數據,這個循環(huán)優(yōu)化就是循環(huán)展開(Brooks,2000)。按照預期,隨著展開因子的增加,執(zhí)行時間和指令數目會減少。我們看到了減少循環(huán)開銷和減少地址計算的效果。功率結果更加有趣,但不太明顯。因為預測器可用來訓練其行為的分支更少且針對循環(huán)結束失敗的最終錯誤預測比例大增,所以隨著循環(huán)進一步展開,分支預測器的準確性出現下降。但是,因為順序取指的連續(xù)數據流不經常被中斷,所以取指階段的效率可以提升。組合的結果是減少了每條指令的凈能耗。
因此盡管執(zhí)行時間基本上低于展開因子4,但是因為功耗持續(xù)降低,所以所有重要的功耗時間積也隨之降低。因此有能耗意識的編譯器或開發(fā)人員與只考慮執(zhí)行時間的編譯器或開發(fā)人員相比,會更傾向于展開循環(huán)。
精度滿足需求即可
還必須考慮輸出要求的精度。即使有浮點硬件可用,定點實現的計算通常比浮點實現的計算更有效率。如果您正在渲染一個供屏幕查看的圖像,可能并不需要完全符合標準,您只需要渲染出可以接受的圖像。
對標準M P E G- 4解碼函數進行遞進優(yōu)化的一項研究(S h i n,2002)已經表明,把軟浮點切換為定點二進制可以把能耗降低72%。精度損失意味著該結果不再符合標準,但是在所研究的系統(tǒng)上仍然足以滿足渲染用途。
關于Thumb
T humb指令集專門設計用于改進代碼密度,還可以提升窄內存系統(tǒng)的性能。但是,在代碼密度確實改進的同時,指令數也同時增加了。這是因為,與A R M指令相比,減少了個別Thumb指令的功能。因此Thumb重新編譯會造成能耗增加,這看起來是合理的,而我們看到的事實也的確是這樣。
上述研究表明,如果代碼大小減少4%,指令執(zhí)行數增加38%,而能耗增加28%。為了找到第三頭大象,我們需要走出處理器及其內存的領域,著眼于范圍更大的系統(tǒng)。我們這些天使用的系統(tǒng)已經被我們的硬件設計同事組合到了一起,這個系統(tǒng)提供了大量節(jié)能選項。
更廣系統(tǒng)中的節(jié)能
顯而易見,沒有使用的組件應盡可能置于低功耗狀態(tài)。這也是所有敏銳的設計系統(tǒng)不可分割的組成部分,這些組件應包括內存和緩存系統(tǒng)、甚至是處理器本身。在多核系統(tǒng)中,我們必須考慮在處理要求相對低時中止一個或多個內核運行的可能性。
首先,一個很小但值得考慮的問題是:處理外設時,要始終嘗試使用中斷機制,而不是輪詢機制。輪詢循環(huán)只會耗用能量而無任何目的。幾乎所有架構均包括了某種等待中斷的指令,可以把這種情況下的系統(tǒng)置于待機狀態(tài)。對于A R M系統(tǒng),內核通常帶有時鐘門控,只保留靜態(tài)漏電。
通過設計中斷架構來增加拖尾連鎖,一般可以避免不必要的睡眠喚醒循環(huán)。ARM Cortex-M3架構可以自動實現這一點。
評論