程式載入
上下文傳遞
系統呼叫
記憶體布局
程序排程
**除錯
程式退出
有同學在群裡聊到編譯器優化的事情,很多時候期望編譯器預設做優化,但是有些場景是希望能繞過的,哪些呢?
這裡舉兩個實實在在的例子。
第乙個,在除錯的時候,如果預設開啟了優化,要關注的某個變數值,用gdb
列印時可能會提示被優化掉了,會讓人丈二和尚摸不著頭腦。
第二個,就是某些場景,編譯器並不理解背後的實際情況,比如說,連續往某個位址寫兩個值,編譯器以為,這不是多此一舉了,幫把最後乙個寫進去就好了,但是殊不知,這個位址可能是個硬體暫存器位址呢,寫第乙個,處理器調整乙個狀態,再寫乙個,再調整乙個狀態,兩個都寫完,才算完整,寫不同的位有不同的含義。
對於第乙個,通常不太需要去改整個核心,比如說,把整個-o2/-os
都拿掉,這時可能引起的莫名情況比去debug
某個問題可能還要棘手。
所以,可以有針對性的,只對某個檔案做優化引數調整即可。
這個本質上是拿掉cflags
裡頭的優化引數,其實用替換就好了,但是可選的用法有:
檔案級:cflags_remove_***.o = -o2
arch/mips/kernel/makefile:
1ifdef config_function_tracer
2cflags_remove_ftrace.o = -pg
3cflags_remove_early_printk.o = -pg
4cflags_remove_perf_event.o = -pg
5cflags_remove_perf_event_mipsxx.o = -pg
6endif
原理如下,就是從原始編譯引數中filter-out
掉特定引數:
1$ grep cflags_remove -ur linux-stable/scripts/makefile.lib
2_c_flags = $(filter-out $(cflags_remove_$(basetarget).o), $(orig_c_flags))
目錄級:kbuild_cflags := $(filter-out -o2, $(kbuild_cflags))
arch/mips/boot/compressed/makefile:
1kbuild_cflags := $(filter-out -pg, $(kbuild_cflags))
自己主動filter-out
掉。也可以直接呼叫指令碼替換:
1kbuild_cflags := $(shell echo $(kbuild_cflags) | sed -e "s/-pg//")
當然,用makefile
內建的filter-out
效率會高,只是方便大家理解邏輯。
怎麼確認這個編譯引數是否真地生效呢,有兩種方法:
一種是直接在相應makefile
列印kbuild_cflags
,例如:$(error $(kbuild_cflags))
,另外一種是make /path/to/***.o v=1
檢視。
在linux lab
裡頭可以用make k-x /path/to/***.o v=1
。
除了直接拿掉,也可以考慮替換成-og
,這個更適合除錯需要。
第二個,也來看看例項:
drivers/cpufreq/loongson2_cpufreq.c:
1static void loongson2_cpu_wait(void)
2
上面中間三句,從gcc
的角度來看,這不是傻嘛,啥也沒做啊,又讀又寫是什麼鬼,目標變數的值根本「沒變」呢。
原因是什麼,這個背後的loongson_chipcfg(0)
是硬體暫存器位址,有它的時序意義,不同的位有不同的意義,寫不同的值會有不同的動作。這個時候就得明確告訴gcc
:
arch/mips/include/asm/mach-loongson64/loongson.h:
1#define loongson_chipcfg(id) (*(volatile u32 *)(loongson_chipcfg[id]))
這種情況怎麼確認呢?make /path/to/***.s
,看看**還在不在。
在「linux lab」
裡頭可以用make k-x /path/to/***.s
。
編譯器優化
常量摺疊 a 1 2 由於結果可預見,編譯器直接生成a 3 常量傳播a 1 若後續 沒有更改a,則編譯器將a直接用其值1代替 減少變數 對於x和y的比較,可以轉換成if i j x i2 y j 2 if x y 複寫傳播 類似於常量長傳,不過傳播的是變數 若後續 未修改a的值,則編譯器用m代替a ...
編譯器優化 乘法優化
由這個想到的 31乘以某個數能不能寫成這個數乘以2的次冪 再減去這個數。用數學語言表達一下就是 設這個數為x 31 x x 2 n x 這個等式是否存在,如果存在,求n的值 那我們計算一下,31 2 n 1 得2 n 32 得n 5 也就是說存在那麼乙個n使得,31乘以某個數的結果等於這個數乘以2的...
編譯器優化問題
今天遇一程式,unsigned char a,b,c a 0x89 b a 1 c a b 在單步除錯的時候,觀察數值發現b的值為0,分析b的值應當為0x44,百思不得其解,通過檢視其彙編語句,發現問題所在。彙編語句如下 mov r7,tmod 0x89 mov a,r7 clr c rrc a a...