亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Linux編譯優化必須掌握的知識點有哪些

發布時間:2021-07-14 11:44:52 來源:億速云 閱讀:216 作者:小新 欄目:服務器

小編給大家分享一下Linux編譯優化必須掌握的知識點有哪些,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

01、編譯選項和內核編譯

Linux內核(英語:linux kernel),是一種計算機操作系統內核,已C語言和匯編語言寫成,匹配POSIX標準,以GNU通用公共許可證發布。從技術上說Linux只是一個內核。“內核”指的是一個提供硬件抽象層、磁盤及文件控制、多任務等功能的系統軟件。

所以首先我們都知道,Linux內核如果用O0編譯,是無法編譯過的,Linux的內核編譯,要么是O2,要么是Os,這點從Linux的Makefile里面可以看出:

Linux編譯優化必須掌握的知識點有哪些

當選擇了

CONFIG_CC_OPTIMIZE_FOR_SIZE

它會是Os,否則就是O2。

其實O2和Os,都是一些優化選項的集合:

gcc -c -Q -O2 --help=optimizers > /tmp/O2-opts

gcc -c -Q -Os --help=optimizers > /tmp/Os-opts

前者傾向于基于速度的優化,后者傾向于基于size更小的優化。對比二者的開關選項:

meld /tmp/O2-opts /tmp/Os-opts

發現差異小的可憐:

Linux編譯優化必須掌握的知識點有哪些

Linux編譯優化必須掌握的知識點有哪些

O2和Os都使能了inline small函數和called once的函數,但是O2里面-finline-functions是關閉的,而Os里面是開的。O2里面optimize-strlen是開的,Os里面這個選項是關閉的。相關選項的含義可以通過"man gcc"看出(有問題,找男人),譬如man gcc后檢索inline-functions:

Linux編譯優化必須掌握的知識點有哪些

從O0到O1,O2,O3,是一個開啟的優化選項逐步加大的過程:

Linux編譯優化必須掌握的知識點有哪些

kernel用O0編譯不過,是因為kernel本身也沒有想用O0能夠編譯過,它的設計里面包含了編譯會優化的假想。下面我們用一個簡單的例子來說明。

02、一個簡單的例子

下面的代碼:

Linux編譯優化必須掌握的知識點有哪些

O0編譯會報如下錯,說f()函數沒有定義:

$ gcc -O0 cc.c

cc.c:1:13: warning: ‘f' used but never defined [enabled by default]

 void f(void);

    ^

/tmp/ccTwwtHG.o: In function `main':

cc.c:(.text+0x19): undefined reference to `f'

collect2: error: ld returned 1 exit status

但是用O2編譯,則沒有問題:

$ gcc -O2 cc.c

原因在于,O2編譯,它意識到a==1,所以if(a>2),它不會成立,所以f()沒有定義也沒有關系。

把代碼稍微改一下后:

Linux編譯優化必須掌握的知識點有哪些

O2這個時候也不行了:

$ gcc -O2 cc.c

/tmp/ccXiyBHn.o: In function `main':

cc.c:(.text.startup+0x7): undefined reference to `f'

collect2: error: ld returned 1 exit status

所以,通過這個例子,大家可以看出來為什么同樣的代碼,用O2就可以過,用O0就過不了。內核里面有許多類似設想編譯器會進行優化的代碼。

3.我們不想inline了

由于編譯的優化,有些函數(比如小函數和全工程里面只被一個人調用的函數)雖然沒有顯示地寫成inline,但是編譯器優化為inline了,這給調試造成了一些麻煩,因為找不到這個函數對應的symbol了。

這個時候,我們可以顯示地寫明某些函數我們不想inline:

Linux編譯優化必須掌握的知識點有哪些

否則,上面2個函數,即便你代碼里面沒有寫inline,由于O2和Os使能了相關的inline選項,也可能被編譯器自動inline掉,如果我們想拒絕inline,可以通過noline來標識。

4.我不想被優化

在全局已經使能O1, O2, O3, Os的情況下,某個單獨的函數我們不想做任何的優化,可以用__attribute__((optimize("O0")))來修飾這個函數,比如我們把上述用O2可以編譯過的代碼進行如下修改:

Linux編譯優化必須掌握的知識點有哪些

重新用O2編譯:

$ gcc -O2 cc.c

/tmp/cc8M338p.o: In function `main':

cc.c:(.text+0x19): undefined reference to `f'

collect2: error: ld returned 1 exit status

5. 總結的話

下面給幾條實踐指南:

  1. 盡量不要嘗試用O0去編譯內核,這不符合真實的工程實踐,也不太被主流Linux社區所支持;內核依賴O2/Os去做較多的優化;

  2. 追求你的代碼在O2的情況下,仍然是正確的,代碼要經得起編譯優化;比如O0工作正常,而O2不正常,應該盡可能從自身找原因,分析匯編;

  3. 如果在全局優化的情況下,想針對某個局部避免優化,可以嘗試用noinline,__attribute__((optimize("O0")))等進行外科手術式地調整。

以上是“Linux編譯優化必須掌握的知識點有哪些”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

无极县| 南华县| 容城县| 澄江县| 屯昌县| 治县。| 江西省| 盖州市| 浦县| 乌拉特前旗| 孟村| 监利县| 都江堰市| 本溪| 商都县| 岱山县| 永川市| 永寿县| 临漳县| 论坛| 特克斯县| 饶河县| 开化县| 新沂市| 博爱县| 定远县| 昆山市| 萨迦县| 上饶市| 肥东县| 通道| 石门县| 阿拉善右旗| 河池市| 滁州市| 民和| 永胜县| 罗定市| 九龙城区| 宜阳县| 惠水县|