GCC編譯優化選項介紹


參考URL:https://blog.csdn.net/qq_31108501/article/details/51842166?

一、為什么要設計編譯優化等級

1、編譯優化是會更改代碼的,所以需要通過不優化的方式進行直譯,便於調試,確定是否是代碼本身的問題,所以就有了優化和不優化的兩個差異;
2、在優化中,不同的優化所得到的效果不一樣,有些是犧牲時間換來空間,而有些是通過犧牲空間換來時間,所以存在不同的優化等級;
3、編譯優化是非常繁雜和易錯的,如果直接采用最激進的優化策略,不僅不能滿足不同用戶的不同需求,更重要的是最激進的策略可能會帶來錯誤;
如果直接采用最激進的策略進行優化,那么編碼階段就必須形成規則進行約束,這么一來對開發人員的要求就很高;

綜上,編譯優化划分了等級,從保守到激進,即使是效率低一些也要確保不出錯。

二、從源碼到可執行文件

gcc 與 g++ 分別是 gnu 的 c & c++ 編譯器 gcc/g++ 在執行編譯工作的時候,總共需要4步:
1、預處理,生成 .i 的文件[預處理器cpp];
2、將預處理后的文件轉換成匯編語言,生成文件 .s [編譯器egcs];
3、有匯編變為目標代碼(機器代碼)生成 .o 的文件[匯編器as];
4、連接目標代碼,生成可執行程序 [鏈接器ld]。

所以編譯優化等級主要在於第二階段生效。

三、編譯優化等級概述(差異)

編譯等級共分為以下幾個等級,各等級均存在不同的應用場景。

  • -O0:

無優化(默認),也是 CFLAGS 或 CXXFLAGS 中沒有設置 -O 等級時的默認等級

  • -O 和-O1:

最基本的優化等級,編譯器會在不花費太多編譯時間(不顯著增加)的同時試圖 生成更快更小的代碼(在編譯大型程序的時候會顯著增加編譯時內存的使用,對於一個大的函數或功能會花費更多的時間和內存)。
由於這些優化是非常基礎的,一般優化任務肯定能順利完成。

  • -O2:

優化等級O1的進階,包含-O1的優化並增加了不需要在目標文件大小和執行速度上進行折衷的優化,此選項將 增加編譯時間和目標文件的執行性能 (編譯器不執行循環展開以及函數內聯)。此選項是推薦的優化等級

  • -Os:

可稱之為 -O2.5,在 -O2 選項的基礎上(基本包含所有,除了對齊優化等),執行 優化程序空間大小 的優化選項,專門優化目標文件大小。可能產生些許問題,不推薦的優化等級。

  • -O3:

這是最高最危險的優化等級,用這個選項會延長編譯代碼的時間,並且在使用 gcc4.x 的系統里不應全局啟用。
自從 3.x 版本以來gcc的行為已經有了極大地改變。在 3.x,-O3生成的代碼也只是比-O2快一點點而已,而 gcc4.x 中還未必更快。用-O3來編譯所有的軟件包將產生更大體積更耗內存的二進制文件,大大增加編譯失敗的機會或不可預知的程序行為(包括錯誤)。在 gcc4.x 中使用-O3是不推薦的。

綜上,沒有特別要求的情況下,建議在使用的時候,直接開 -O2 的優化等級,有問題的時候調整為 -O0 進行調試
如果對自己代碼比較有把握的時候,可以直接上 -O3;
如果 -O2 和 -O1 編譯的目標文件大小差異較大,並且對尺寸有要求,可以上 -O1。

四、編譯優化等級詳述(補充)

-O1 優化選項
在不影響調試的前提下,-O1 優化選項也會添加 -fomit-frame-pointer 選項。 
在ADA編譯器上,-O1 不會添加 -ftree-sra 選項,想在ADA編譯器下使用該選項,必須明確的在命令行指出。

-O3 優化選項
打開所有-O2的優化選項並且增加 -finline-functions,-funswitch-loops,-fpredictive-commoning,-fgcse-after-reloadand -ftree-vectorize 優化選項。

五、小結

  • -O0 不進行任何優化。

  • -O1 優化會消耗一些的編譯時間,它主要對代碼的分支,常量以及表達式等進行優化。

  • -O2 嘗試更多的寄存器級的優化以及指令級的優化,它會在編譯期間占用更多的內存和編譯時間。

  • -O3 在O2的基礎上進行更多的優化,例如使用偽寄存器網絡,普通函數的內聯,以及針對循環的更多優化。


免責聲明!

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



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