你真的了解編譯器的優(yōu)化等級嗎?
導(dǎo)語:項目開發(fā)過程中我們?yōu)槭裁匆x擇編譯的優(yōu)化等級?
在目前的嵌入式開發(fā)過程中,編譯的時候編譯器都具有多項的優(yōu)化等級,其目的是為了減少代碼大小或者提高應(yīng)用程序的性能。不同的優(yōu)化等級,有著不同的優(yōu)化目標(biāo)。所以對于某個目標(biāo)進行優(yōu)化的時候,會對其他目標(biāo)產(chǎn)生一些影響。優(yōu)化等級的選擇是在不同的優(yōu)化目的中尋找一個平衡點。
一、那么目前有哪些優(yōu)化等級?對應(yīng)優(yōu)化等級所優(yōu)化的是那部分的內(nèi)容?
1.-O0:沒有優(yōu)化
使用-O0?結(jié)果可以加快編譯和構(gòu)建時間,但比其他優(yōu)化等級生成的代碼要慢。與其他優(yōu)化等級相比,代碼大小和堆棧使用率明顯更高。生成的代碼與源代碼緊密相關(guān),但是生成的代碼量更大,包括無用的代碼。
2.-O1:有限優(yōu)化
在編譯器中啟用核心優(yōu)化。此優(yōu)化等級提供了良好的調(diào)試體驗,并具有比-O0更好的代碼質(zhì)量,堆棧使用率也提高了。
3.-O2:優(yōu)化速度
有更高的性能優(yōu)化。增加了一些新的優(yōu)化,并更改了優(yōu)化的啟發(fā)式方法。這是編譯器可能生成矢量指令的第一個優(yōu)化等級。它會降低調(diào)試體驗,并且由于許多循環(huán)展開和函數(shù)內(nèi)聯(lián),代碼大小將增加。
4.-O3:優(yōu)化速度
有更高的性能優(yōu)化。此優(yōu)化等級允許進行需要大量編譯時分析和資源的優(yōu)化。-O3指示編譯器針對生成的代碼的性能進行優(yōu)化,而忽略生成的代碼的大小,這可能會導(dǎo)致代碼大小增加,比-O2生成的代碼更大。但速度會比比-O2快
5.-Os:平衡的優(yōu)化
目的是在不顯著增加代碼大小的情況下提供高性能,即速度的優(yōu)化和代碼大小的增加是合理的。根據(jù)你的應(yīng)用程序,提供的性能可能類似于?-O2或-O3。
6.-Oz:純粹優(yōu)化代碼大小
目的是提供盡可能小的代碼量。在開發(fā)過程中,建議使用此選項以獲得最佳代碼大小。但是,此優(yōu)化等級會降低調(diào)試體驗。
7.-Ofast:
從-O3級開始執(zhí)行優(yōu)化。該等級還執(zhí)行其他進一步的優(yōu)化,可能會違反嚴(yán)格遵守語言標(biāo)準(zhǔn)的要求。與-O3相比,該等級會降低調(diào)試體驗,并可能導(dǎo)致代碼大小增加。
8.-Omax:最大程度的優(yōu)化
執(zhí)行最大限度的優(yōu)化,并專門針對性能優(yōu)化。它啟用了-Ofast和鏈接時間優(yōu)化(LTO)的所有優(yōu)化。在此優(yōu)化等級上,編譯器是有可能會違反嚴(yán)格遵守語言標(biāo)準(zhǔn)的規(guī)定。使用此優(yōu)化等級可獲得最快的性能。與-Ofast相比,該等級會降低調(diào)試體驗,并可能導(dǎo)致代碼大小增加。
二、優(yōu)化等級之間的比較
1.-O1與-O0相比:
(1)-O1啟用優(yōu)化,這可能會降低調(diào)試信息的完整度。
(2)-O1啟用了內(nèi)聯(lián),這意味著回溯可能不會提供讀取源代碼所期望的開放函數(shù)激活堆棧。
(3)-O1不會調(diào)用沒有使用或沒有預(yù)期調(diào)用的函數(shù),代碼量更小。
2.-O2與-O1相比:
(1)-O2執(zhí)行的循環(huán)展開量(一種犧牲程序的尺寸來加快程序的執(zhí)行速度的優(yōu)化方法)可能會增加。
(2)-O2可以為簡單循環(huán)和獨立標(biāo)量運算的相關(guān)序列生成矢量指令。
3.-O3與-O2相比:
(1)-O3執(zhí)行的循環(huán)展開量增加。
(2)-O3在編譯器流水線后期中啟用更積極的指令優(yōu)化。
4.-Os與-O3相比:
(1)-Os與-O3相比,可減少代碼大小。但會降低調(diào)試體驗。
(2)顯著降低了執(zhí)行的循環(huán)展開量。
5.-Oz與-Os相比:
(1)編譯器僅針對代碼大小進行優(yōu)化,而忽略性能優(yōu)化,這可能會導(dǎo)致代碼變慢。
(2)未禁用功能內(nèi)聯(lián)。在某些情況下,內(nèi)聯(lián)可能會整體上減少代碼大小,例如,如果一個函數(shù)僅被調(diào)用一次。僅當(dāng)預(yù)期代碼大小會減小時,才將內(nèi)聯(lián)啟發(fā)式方法調(diào)整為內(nèi)聯(lián)式。
(3)禁用可能會增加代碼大小的優(yōu)化,例如循環(huán)展開和循環(huán)矢量化。
(4)循環(huán)是作為while循環(huán)而不是do-while循環(huán)生成的。
6.-Omin與-Oz相比:
(1)-Omin啟用了一組基本的鏈接時間優(yōu)化(LTO),旨在刪除未使用的代碼和數(shù)據(jù),同時也試圖優(yōu)化全局內(nèi)存訪問。
(2)-Omin支持虛函數(shù)消除,這對c++用戶來說是一個特別的好處。
三、那么說的那么多,我們到底要怎么選擇優(yōu)化等級呢?
簡單來說,
想要工程代碼小,那就-Oz和-Omin
想要工程有更好的性能,那就選-O2,-O3,-Ofast,-Omax
想要良好的調(diào)試過程,那就選-O1
想要源代碼和生成的代碼之間有更好的相關(guān)性或者想要更快的編譯速度,那就-O0
又想要工程代碼小還要有好的性能,那就-Os
完
