首先我們都知道,linux
核心如果用o0
編譯,是無法編譯過的,linux
的核心編譯,要麼是o2
,要麼是os
,這點從linux
的makefile
裡面可以看出:
當選擇了
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
發現差異小的可憐:
o2
和os
都使能了inline small
函式和called once
的函式,
但是o2
裡面-finline-functions
是關閉的,而os
裡面是開的。
o2
裡面optimize-strlen
是開的,os
裡面這個選項是關閉的。
相關選項的含義可以通過"man gcc"
看出(有問題,找男人),譬如man gcc
後檢索inline-functions
:
從o0
到o1
,o2
,o3
,是乙個開啟的優化選項逐步加大的過程:
kernel
用o0
編譯不過,是因為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
,由於o2
和os
使能了相關的inline
選項,也可能被編譯器自動inline
掉,如果我們想拒絕inline
,可以通過noline
來標識。
在全域性已經使能o1
,o2
,o3
,os
的情況下,某個單獨的函式我們不想做任何的優化,可以用__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 前者傾向於基...