Arm嵌入式編譯器可以執(zhí)行一些優(yōu)化來(lái)減少代碼量并提高應(yīng)用程序的性能。不同的優(yōu)化級(jí)別有不同的優(yōu)化目標(biāo),不僅如此,針對(duì)某個(gè)目標(biāo)進(jìn)行優(yōu)化會(huì)對(duì)其他目標(biāo)產(chǎn)生影響。比如想減小生成的代碼量,勢(shì)必會(huì)影響到該代碼的性能。所以?xún)?yōu)化級(jí)別總是這些不同目標(biāo)(代碼量,程序性能,debug信息)之間的權(quán)衡。
目錄
Optimization level -O0
Optimization level -O1?
Optimization level -O2
Optimization level -O3
Optimization level -Os
Optimization level -Oz
Optimization level -Omin
Optimization level -Ofast
Optimization level -Omax
Arm Compiler for Embedded提供了各種優(yōu)化級(jí)別來(lái)控制不同的優(yōu)化目標(biāo):
優(yōu)化目標(biāo) | 可用的優(yōu)化級(jí)別 |
---|---|
更小的代碼量 |
-Oz ,?-Omin
|
更快的性能 |
-O2 ,?-O3 ,?-Ofast ,?-Omax
|
兼顧代碼量和debug信息 | -O1 |
源代碼和生成代碼之間更好的相關(guān)性 |
-O0 ?(no optimization) |
更快的編譯和構(gòu)建時(shí)間 |
-O0 ?(no optimization) |
在代碼量和性能之間的平衡 | -Os |
- 如果對(duì)性能使用更高的優(yōu)化級(jí)別,那么它對(duì)其他目標(biāo)的影響也會(huì)更大,例如調(diào)試體驗(yàn)降低、代碼大小增加和編譯和構(gòu)建時(shí)間增加。
- 如果優(yōu)化目標(biāo)是減少代碼大小,那么它會(huì)對(duì)其他目標(biāo)產(chǎn)生影響,例如降低調(diào)試體驗(yàn)、降低性能和增加編譯和構(gòu)建時(shí)間。?
所以用戶(hù)可以根據(jù)自己的編譯目標(biāo),選擇適合自己的編譯優(yōu)化等級(jí):
Optimization level -O0
-O0?將禁用所有優(yōu)化。
這個(gè)優(yōu)化級(jí)別是默認(rèn)的。使用-O0的結(jié)果是更快的編譯和構(gòu)建時(shí)間,但產(chǎn)生的代碼,其性能比其他優(yōu)化級(jí)別低,代碼大小和堆棧使用也會(huì)明顯高于其他優(yōu)化級(jí)別。由于沒(méi)有任何優(yōu)化,所以生成的代碼與源代碼密切相關(guān),這導(dǎo)致生成的代碼明顯更多,包括死代碼(dead code)。
Optimization level -O1?
-O1在編譯器中啟用內(nèi)核優(yōu)化(core optimizations)。-O1便于用戶(hù)調(diào)試,代碼質(zhì)量?jī)?yōu)于-O0。此外,堆棧的使用也比使用-O0時(shí)得到了改善。如果想調(diào)試程序,建議使用-O1來(lái)獲取更多的調(diào)試信息。與使用-O0相比,使用-O1的不同之處在于:
- 啟用了優(yōu)化,這可能會(huì)降低調(diào)試信息的保真度(fidelity)。
- 啟用了內(nèi)聯(lián),這意味著函數(shù)調(diào)用棧的回溯,可能不會(huì)像閱讀源代碼那樣,具有層級(jí)關(guān)系,內(nèi)聯(lián)會(huì)把函數(shù)體直接加載到函數(shù)調(diào)用的地方。
- 如果不需要函數(shù)返回的結(jié)果,則一個(gè)沒(méi)有副作用的函數(shù)在預(yù)期的地方可能不會(huì)被調(diào)用,甚至?xí)缓雎浴?/li>
- 局部變量的值在不再使用后可能無(wú)法在其作用域中被獲取使用。例如,它們所在棧位置可能已經(jīng)被其他模塊使用了。
Optimization level -O2
與-O1相比,-O2對(duì)性能進(jìn)行了更高的優(yōu)化。這一層是編譯器自動(dòng)生成矢量指令(vector instructions)的第一個(gè)優(yōu)化層。它還降低了調(diào)試體驗(yàn),并且可能導(dǎo)致代碼量的增加。與使用- O1相比,使用-O2的不同之處在于:
- 增加內(nèi)聯(lián)函數(shù)調(diào)用的閾值。
- 執(zhí)行的循環(huán)展開(kāi)次數(shù)可能會(huì)增加。
- 矢量指令可以為簡(jiǎn)單循環(huán)和獨(dú)立標(biāo)量操作的相關(guān)序列生成??梢允褂胊rmclang命令行選項(xiàng)-fno-vectorize來(lái)禁止矢量指令的創(chuàng)建。
Optimization level -O3
與-O2相比,-O3是更高的性能優(yōu)化。此優(yōu)化級(jí)別需要大量編譯時(shí)分析和資源的優(yōu)化,-O3指示編譯器優(yōu)化生成代碼的性能,而忽略生成代碼的量,這可能導(dǎo)致代碼量增加。與-O2相比,它還降低了調(diào)試體驗(yàn)。并且:
- 增加內(nèi)聯(lián)函數(shù)調(diào)用的閾值。
- 執(zhí)行的循環(huán)展開(kāi)次數(shù)可能會(huì)增加。
- 在編譯器流水線(xiàn)上,實(shí)施更加激進(jìn)的指令優(yōu)化策略。
Optimization level -Os
-Os的目標(biāo)是在不顯著增加代碼大小的情況下提供高性能。取決于用戶(hù)的代碼,-Os提供的性能可能與-O2或-O3相似。與-O3相比,-Os減少了代碼量。與-O1相比,它還降低了調(diào)試體驗(yàn)。與使用-O3相比,使用-Os的不同之處在于:
- 降低了內(nèi)聯(lián)函數(shù)調(diào)用的閾值。
- 執(zhí)行的循環(huán)展開(kāi)的數(shù)量顯著降低。
Optimization level -Oz
-Oz的目標(biāo)是在不使用鏈接時(shí)間優(yōu)化(LTO)的情況下提供更小的代碼量。如果LTO不適合用戶(hù)的應(yīng)用程序,Arm建議可以使用此選項(xiàng)以獲得最佳代碼大小。與-O1相比,此優(yōu)化級(jí)別降低了調(diào)試體驗(yàn)。與使用-Oz相比:
- 編譯器只針對(duì)代碼大小進(jìn)行優(yōu)化,而忽略性能優(yōu)化,這可能導(dǎo)致代碼變慢。
- 未禁用函數(shù)內(nèi)聯(lián)。在某些情況下,內(nèi)聯(lián)可以減少總體代碼大小,例如,如果一個(gè)函數(shù)只被調(diào)用一次。
- 禁止一些可能增加代碼量的優(yōu)化,比如將循環(huán)展開(kāi),循環(huán)矢量化等。
- 針對(duì)M系列的AArch32以及其他的AArch64目標(biāo),將使能外聯(lián)(outlining)功能。外聯(lián)器(outliner?)將搜索代碼中相同sequence的代碼,并將它們放在同一個(gè)函數(shù)當(dāng)中,然后用調(diào)用同一個(gè)函數(shù)的方式來(lái)取代這些相同的代碼段。外聯(lián)可以減小代碼大小,但是增加了代碼執(zhí)行時(shí)間。用戶(hù)可以使用-moutline, -mno-outline選項(xiàng)來(lái)手動(dòng)開(kāi)啟或者關(guān)閉該功能。
Optimization level -Omin
通過(guò)使用LTO功能的子集,-Omin旨在提供比-Oz更小的代碼量。與使用-Oz相比,使用-Omin的不同之處在于:
- -Omin支持一組基本的LTO,旨在刪除未使用的代碼和數(shù)據(jù),同時(shí)還嘗試優(yōu)化全局內(nèi)存訪(fǎng)問(wèn)。
- -Omin支持消除虛函數(shù)(C++)。
如果希望在-Omin下進(jìn)行編譯,并使用單獨(dú)的編譯和鏈接步驟,那么還必須在armlink命令行中包含-Omin。
Optimization level -Ofast
-Ofast執(zhí)行-O3級(jí)的優(yōu)化,包括那些使用armclang選項(xiàng)-ffast-math執(zhí)行的優(yōu)化。該級(jí)別還執(zhí)行其他可能違反嚴(yán)格遵守語(yǔ)言標(biāo)準(zhǔn)的激進(jìn)優(yōu)化。與-O3相比,此級(jí)別降低了調(diào)試體驗(yàn),并且可能導(dǎo)致代碼大小增加。
Optimization level -Omax
-Omax執(zhí)行最大優(yōu)化,并專(zhuān)門(mén)針對(duì)性能優(yōu)化。它支持從-Ofast到LTO的所有優(yōu)化。在這個(gè)優(yōu)化級(jí)別上,Arm嵌入式編譯器可能會(huì)違反嚴(yán)格遵守語(yǔ)言標(biāo)準(zhǔn)。使用此優(yōu)化級(jí)別可以獲得最快的性能。與-Ofast相比此級(jí)別降低了調(diào)試體驗(yàn),并且可能導(dǎo)致代碼大小增加。如果用戶(hù)希望在-Omax下進(jìn)行編譯,并且有單獨(dú)的編譯和鏈接步驟,那么您還必須在armlink命令行中包含-Omax。
示例
int test()
{
int x=10, y=20;
int z;
z=x+y;
return 0;
}
在上述代碼中,int x=10
?和z=x+y ,兩行代碼為死代碼(
dead code),如果使用-O0,則不進(jìn)行任何優(yōu)化,這兩行將會(huì)被編譯生成到源文件中:
armclang --target=arm-arm-none-eabi -march=armv7-a -O0 -S file.c
如果使用-O1,這兩行將會(huì)被忽略:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-603019.html
armclang --target=arm-arm-none-eabi -march=armv7-a -O1 -S file.c文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-603019.html
Selecting optimization optionshttps://developer.arm.com/documentation/100748/0620/Using-Common-Compiler-Options/Selecting-optimization-options?lang=en
到了這里,關(guān)于A(yíng)RM嵌入式編譯器編譯優(yōu)化選項(xiàng) -O的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!