宋寶華 關於Linux編譯優化幾個必須掌握的姿勢

2021-10-05 04:39:39 字數 3593 閱讀 2438

首先我們都知道,linux核心如果用o0編譯,是無法編譯過的,linux的核心編譯,要麼是o2,要麼是os,這點從linuxmakefile裡面可以看出:

當選擇了

config_cc_optimize_for_size

它會是os,否則就是o2

其實o2os,都是一些優化選項的集合:

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

發現差異小的可憐:

o2os都使能了inline small函式和called once的函式,

但是o2裡面-finline-functions是關閉的,而os裡面是開的。

o2裡面optimize-strlen是開的,os裡面這個選項是關閉的。

相關選項的含義可以通過"man gcc"看出(有問題,找男人),譬如man gcc後檢索inline-functions

o0o1o2o3,是乙個開啟的優化選項逐步加大的過程:

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

下面的**:

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()沒有定義也沒有關係。

把**稍微改一下後:

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就過不了。核心裡面有許多類似設想編譯器會進行優化的**。

由於編譯的優化,有些函式(比如小函式和全工程裡面只被乙個人呼叫的函式)雖然沒有顯示地寫成inline

但是編譯器優化為inline了,這給除錯造成了一些麻煩,因為找不到這個函式對應的symbol了。

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

否則,上面2個函式,即便你**裡面沒有寫inline,由於o2os使能了相關的inline選項,也可能被編譯器自動inline掉,如果我們想拒絕inline,可以通過noline來標識。

在全域性已經使能o1o2o3os的情況下,某個單獨的函式我們不想做任何的優化,可以用__attribute__((optimize("o0")))來修飾這個函式,比如我們把上述用o2可以編譯過的**進行如下修改:

重新用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

下面給幾條實踐指南:

字元裝置驅動 globalmem 宋寶華第6章

1.在模組的載入中要實現裝置號的申請與cdev的註冊。先用int register chrdev region dev t from,unsigned count,const char name 或者int alloc chrdev region dev t dev,unsigned basemin...

宋寶華談 C 語言嵌入式系統程式設計修煉之一 背景篇

宋寶華談 c 語言嵌入式系統程式設計修煉之一 背景篇 不同於一般形式的軟體程式設計,嵌入式系統程式設計建立在特定的硬體平台上,勢必要求其程式語言具備較強的硬體直接操作能力。無疑,組合語言具備這樣的特質。但是,歸因於組合語言開發過程的複雜性,它並不是嵌入式系統開發的一般選擇。而與之相比,c 語言 一種...

關於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 前者傾向於基...