01、編譯選項和內核編譯
Linux內核(英語:linux kernel),是一種計算機操作系統內核,已C語言和匯編語言寫成,匹配POSIX標準,以GNU通用公共許可證發布 。從技術上說Linux只是一個內核 。“內核”指的是一個提供硬件抽象層、磁盤及文件控制、多任務等功能的系統軟件 。
所以首先我們都知道,Linux內核如果用O0編譯,是無法編譯過的,Linux的內核編譯,要么是O2,要么是Os,這點從Linux的Makefile里面可以看出:

當選擇了
CONFIG_CC_OPTIMIZE_FOR_SIZE它會是Os,否則就是O2 。
其實O2和Os,都是一些優化選項的集合:
gcc -c -Q -O2 --help=optimizers > /tmp/O2-optsgcc -c -Q -Os --help=optimizers > /tmp/Os-opts前者傾向于基于速度的優化,后者傾向于基于size更小的優化 。對比二者的開關選項:
meld /tmp/O2-opts /tmp/Os-opts 發現差異小的可憐:


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,是一個開啟的優化選項逐步加大的過程:

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

O0編譯會報如下錯,說f()函數沒有定義:
$ gcc -O0 cc.ccc.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()沒有定義也沒有關系 。
把代碼稍微改一下后:

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:

否則,上面2個函數,即便你代碼里面沒有寫inline,由于O2和Os使能了相關的inline選項,也可能被編譯器自動inline掉,如果我們想拒絕inline,可以通過noline來標識 。
推薦閱讀
- linux系統shell腳本定時統計Nginx下access.log的PV并發送給API保存到數據庫
- Linux系統中有效地管理進程的8個命令介紹說明
- Linux系統下virtuoso數據庫安裝與使用詳解教程
- 怎么忽略省電優化?
- Deepin Linux怎么安裝?Deepin Linux安裝步驟簡述
- 香港站群服務器助力網站SEO優化
- 低質量頁面是否影響整站優化效果?
- 建設H.265解決方案,如何在linux下對圖像做H.265
- 企業網站優化怎么才有效果
- n900v安卓5.0root包,想不到2019年還有人想做Linux
