KEIL中程序優化說明


優化級別說明(僅供參考) :
則其中的 Code Optimization 欄就是用來設置 C51 的優化級別。共有 9 個優化
級別(書上這么寫的) ,高優化級別中包含了前面所有的優化級別。現將各個級
別說明如下:
0 級優化:
1、 常數折疊:只要有可能,編譯器就執行將表達式化為常數數字的計算,其中
包括運行地址的計算。
2、 簡單訪問優化:對 8051 系統的內部數據和位地址進行訪問優化。
3、 跳轉優化:編譯器總是將跳轉延至最終目標上,因此跳轉到跳轉之間的命令
被刪除。
1 級優化:
1、 死碼消除:無用的代碼段被消除。
2、 跳轉否決:根據一個測試回溯,條件跳轉被仔細檢查,以決定是否能夠簡化
或刪除。
2 級優化:
1、 數據覆蓋:適於靜態覆蓋的數據和位段被鑒別並標記出來。連接定位器 BL51
通過對全局數據流的分析,選擇可靜態覆蓋的段。
3 級優化:
1窺孔優化:將冗余的 MOV 命令去掉,包括不必要的從存儲器裝入對象及
裝入常數的操作。另外如果能節省存儲空間或者程序執行時間,復雜操作將由簡
單操作所代替。
4 級優化:
1、 寄存器變量:使自動變量和函數參數盡可能位於工作寄存器中,只要有可能,
將不為這些變量保留數據存儲器空間。
2、擴展訪問優化:來自 IDATAXDATAPDATA CODE 區域的變量直接包
含在操作之中,因此大多數時候沒有必要將其裝入中間寄存器。
3、局部公共子式消除:如果表達式中有一個重復執行的計算,第一次計算的結
果被保存,只要有可能,將被用作后續的計算,因此可從代碼中消除繁雜的計算。
4CASE/SWITCH 語句優化: 將 CASE/SWITCH 語句作為跳轉表或跳轉串優化。
5 級優化:
1、 全局公共子式消除:只要有可能,函數內部相同的子表達式只計算一次。中
間結果存入一個寄存器以代替新的計算。
2、 簡單循環優化:以常量占據一段內存的循環再運行時被優化。
6 級優化:
1、 回路循環:如果程序代碼能更快更有效地執行,程序回路將進行循環。
7 級優化:
1、 擴展入口優化:在適合時對寄存器變量使用 DPTR 數據指針,指針和數組訪
問被優化以減小程序代碼和提高執行速度。
8 級優化:
1、 公共尾部合並:對同一個函數有多處調用時,一些設置代碼可被重復使用,
從而減小程序代碼長度。
9 級優化:
1、 公共子程序塊:檢測重復使用的指令序列,並將它們轉換為子程序。C51
至會重新安排代碼以獲得更多的重復使用指令序列。
當然,優化級別並非越高越好,應該根據具體要求適當選擇。
KeilC51 的編譯器有一個優化設置,不同的優化設置,會產生不同的編譯結果。一
般情況缺省編譯優化設置被設定為 8 級優化,實際最高可設定為 9 級優化:
1. Dead code elimination
2.Data overlaying
3.Peephole optimization
4.Register variables
5.Common subexpression elimination
6.Loop rotation
7.Extended Index Access Optimizing
8.Reuse Common Entry Code
9.Common Block Subroutines
附表:Keil C51 中的優化級別及優化作用 級別 說明
0 常數合並:編譯器預先計算結果,盡可能用常數代替表達式。包括運行
地址計算。
優化簡單訪問:編譯器優化訪問 8051 系統的內部數據和位地址。
跳轉優化:編譯器總是擴展跳轉到最終目標,多級跳轉指令被刪除。
1 死代碼刪除:沒用的代碼段被刪除。
拒絕跳轉:嚴密的檢查條件跳轉,以確定是否可以倒置測試邏輯來改進或刪除。
2 數據覆蓋:適合靜態覆蓋的數據和位段被確定,並內部標識。BL51
/定位器可以通過全局數據流分析,選擇可被覆蓋的段。
3 窺孔優化:清除多余的 MOV 指令。這包括不必要的從存儲區加載和常
數加載操作。當存儲空間或執行時間可節省時,用簡單操作代替復雜操作。
4 寄存器變量:如有可能,自動變量和函數參數分配到寄存器上。為這些
變量保留的存儲區就省略了。
優化擴展訪問:IDATAXDATAPDATA CODE 的變量直接包含在操作中。
在多數時間沒必要使用中間寄存器。
局部公共子表達式刪除:如果用一個表達式重復進行相同的計算,則保存第一次
計算結果,后面有可能就用這結果。多余的計算就被刪除。
Case/Switch 優化:包含 SWITCH CASE 的代碼優化為跳轉表或跳轉隊列。
5 全局公共子表達式刪除: 一個函數內相同的子表達式有可能就只計算一
次。中間結果保存在寄存器中,在一個新的計算中使用。
簡單循環優化:用一個常數填充存儲區的循環程序被修改和優化。
6 循環優化:如果結果程序代碼更快和有效則程序對循環進行優化。
7 擴展索引訪問優化:適當時對寄存器變量用 DPTR。對指針和數組訪問
進行執行速度和代碼大小優化。
8 公共尾部合並:當一個函數有多個調用,一些設置代碼可以復用,因此
減少程序大小。
9 公共塊子程序:檢測循環指令序列,並轉換成子程序。Cx51 甚至重排
代碼以得到更大的循環序列。
優化論
談到優化,其實很多人都哭笑不得,因為在一個 C51 軟件工程師的生涯中,總要被
KEIL 的優化耍那么一次到幾次。 我被耍過,想必看着文章的你也被耍過,如果你回
答說不,那只能說你寫的 C51 程序不多!
看看 KEILC 的優化級別選項吧:
0-9 10 個級別的優化,0 是最低,9 最高,一個普通的程序,設置最高級別和最低級
,編譯后代碼量有時會相差很遠,DX DEMO 程序為例,0 級優化后是 14K
CODE,9 級優化后是 10K CODE,前后相差了 4K。 可見這個差別是多么的大。
事實上我們不需要知道對應的各個級別 KEIL會如何優化你的程序或優化了些什
,我們只需要以一種嚴謹的態度去編寫和對待你的程序就可以了。在我個人的
觀念中,程序在 9 級優化后依然能保持完美無誤的運行,你才算了解 KEIL 的脾氣。
好了,還是說點正點的:
有些人習慣整體程序都選擇同一個優化級,事實上每個 C 文件都可以有獨立的優
化級別的:
在工作區右鍵選擇你的模塊(.C)然后選取 Options for File xxx 就會出現如下界
:
C51 選項中就可以選擇優化級別和警告級別等東西了,被獨立設置過的 C 文件
會有特殊的標記的:
用以提醒你這個文件的編譯處理並非默認設置!
如果你覺得模塊優化都不夠細的話,你可以考慮局部優化,也就是說對某個函數實
行某個級別的優化。當你發現 9 級優化的時候某個函數總是變的不正常,但你又
希望其它函數和程序段保持最高的簡潔度,那么局部優化可以說是相當有用的
了。在 KEIL 手冊中有介紹這個功能:
#pragma OPTIMIZE(x) x 就是你希望的優化級別,一般應用如下:
#pragma OPTIMIZE(6)
void FunA()
{ }
......
......
#pragma OPTIMIZE(9)
void FunB()
{ }
上面的意思就是說,void FunA()void FunB()之前的所有函數,包括 FunA 在內,
都采用 6 級的優化,而從 FunB 開始直到之后,只要沒碰上#pragma OPTIMIZE,都采
9 級優化了。
OPTIMIZE 還可以多一個參數,就是 speed size,
用法: #pragma OPTIMIZE(9,speed)#pragma OPTIMIZE(5,size
對應的就是 9 級優化,以速度為主,5 級優化,以空間最小為主。
在實際使用時發現仿真時有寫程序是白色的無法進行斷點設置
搜索到的答案是優化等級過高,一些普通的程序被優化。
只得把優化程序等級降低。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM