單片機編程軟件是單片機開發(fā)不可缺少的工具之一,目前市場流通的單片機編程軟件主要為IAR單片機編程軟件和KEIL單片機編程軟件。
一、編譯優(yōu)化選項
在iar中可以設(shè)置代碼的編譯優(yōu)化等級,在工程名上右鍵選Options.。.,在彈框中選C/C++ Compiler--Optimizations,如下圖所示。
左邊的level里面是優(yōu)化等級,右邊的是附加選項。如果不想往下看了又有bug體質(zhì),就把這里的level選到None上面,點擊OK。
二、優(yōu)化還是不優(yōu)化
優(yōu)化的目的簡單來說主要有兩個,減少代碼量和提高程序運行效率。隨之而來的是什么呢?如果編譯器誤認為你寫的延時是“低效率”代碼,如果編譯器認為某些變量的生命周期可以提前結(jié)束了,如果編譯器認為某些變量你定義了沒有使用就是沒用,就會原地爆炸了。
所以還是有必要搞明白,優(yōu)化到底優(yōu)化了什么,才能決定要不要優(yōu)化。
三、IAR優(yōu)化了什么
1.None
有最好的debug支持,變量的生命周期會貫穿它的整個作用域,也就是說編譯器不做任何優(yōu)化,只要是變量的作用域,這個變量就是有效的。
最直觀的的體現(xiàn)就是可以在live watch中查看該變量,如果它被優(yōu)化了,就查看不了了。
2.Low
仍然是具備調(diào)試支持的,優(yōu)化的是變量的生命周期,如果一個變量沒有作用了,后面不會用到它了,就會把它優(yōu)化掉,不讓它貫穿它的整個生命周期。
這有什么好處呢?這個變量不存在了,就意味著寄存器的壓力減小了很多,可以騰出更多空間給更有需要的變量。
3.Medium
除了上述優(yōu)化以外,還加入了很多新的優(yōu)化。
· Live-dead analysis and optimization
代碼是否可用的分析和優(yōu)化
· Dead code elimination
無用的代碼清除。
· Redundant label elimination
冗余標簽消除
· Redundant branch elimination
冗余分支清除,所以可能出現(xiàn)由于對變量和分支的共同優(yōu)化,導致某些條件分支明明成立卻始終不會進入,一個大坑。
· Code hoisting
代碼提升,很難理解的名字,其實就是它字面意思,就是把某些代碼(變量定義)提到作用域的頂部去,可笑的是定義的順序不變。也就是說,你定義了全局變量a=1,然后在某個函數(shù)里輸出a,在下面定義局部變量a=2,最后輸出的結(jié)果是亂碼或者0,這取決于局部變量的默認初始化的值。在函數(shù)里真正被輸出的,不是全局變量的a,而是局部變量的a,但是這個a只做了定義,初始化還在原位置。
· Peephole optimization
窺孔優(yōu)化,通俗點說是局部優(yōu)化,編譯器對部分編譯的代碼,結(jié)合目標CPU的指令特點,做一些認為可以提高性能的優(yōu)化。
· Some register content analysis and optimization
寄存器內(nèi)容分析與優(yōu)化
· Static clustering
靜態(tài)聚類。將在同一模塊內(nèi)定義的靜態(tài)變量和全局變量布置成使得在相同函數(shù)中訪問的變量彼此緊密地存儲。這使得編譯器可以為多個訪問使用相同的基指針。
· Common subexpression elimination
公共子表達式消去,在編程中會有很多地方使用相似的表達式,比如:
a=b+c+d;
e=b+c+f;
這個時候可以優(yōu)化成這樣:
tem=b+c;
a=tem+d;
e=tem+f;
4.High
最高程度的優(yōu)化。具備以上所有的優(yōu)化之外,還有:
· Instruction scheduling
指令調(diào)度,編譯器根據(jù)自己的指令調(diào)度器去重新安排指令,使得處理器運行時出現(xiàn)的資源沖突情況更少,從而減少資源沖突引起的卡頓情況。
· Cross jumping
交叉跳躍
· Advanced register content analysis and optimization
高級寄存器內(nèi)容分析與優(yōu)化
· Loop unrolling
循環(huán)展開。有一些小的循環(huán)體,在編譯時就能確定其循環(huán)次數(shù),編譯器會啟發(fā)式得試探是否將這個循環(huán)體復制展開,展開循環(huán)體能減少程序的迭代次數(shù),從而加快程序的運行速度,但會增加代碼的大小。
編譯器會從速度和代碼大小之間去找一個平衡點,優(yōu)化速度和優(yōu)化代碼大小那個配置就會影響這個優(yōu)化。
· Function inlining
函數(shù)內(nèi)聯(lián)
如果一個比較小的函數(shù)在編譯時已經(jīng)能確定其準確的定義了,編譯器會決定將其內(nèi)聯(lián)到調(diào)用者的內(nèi)部,這樣就會減小函數(shù)調(diào)用的開銷。
· Code motion
代碼移動。對循環(huán)不變的表達式和公共子表達式進行移動,避免其被再次評估。這個優(yōu)化會減小程序代碼體積,加快執(zhí)行速度。
· Type-based alias analysis
基于類型的別名分析。多個指針指向同一塊內(nèi)存,可以互相稱之為內(nèi)存的別名,因為這種情況會導致優(yōu)化變得很困難,因為編譯的時候不知道內(nèi)存是否存在。所以編譯器采用假設(shè)按照定義的類型分配了內(nèi)存去編譯優(yōu)化。
說明:上面有些優(yōu)化,可以在iar中配置是否要使用。
高級別的優(yōu)化選項回增加代碼編譯的時間,并且會在調(diào)試的時候出現(xiàn)一些困難,比如有時候想在某個位置打斷點卻發(fā)現(xiàn)打不上,因為那里的代碼已經(jīng)被優(yōu)化掉了,有時候想看某些變量的值,卻發(fā)現(xiàn)live watch顯示這個變量無法查看,也是被優(yōu)化掉了。
責任編輯;zl
評論
查看更多