Linux 下如何繞過編譯器優化

2021-10-05 04:39:39 字數 2669 閱讀 2076

程式載入

上下文傳遞

系統呼叫

記憶體布局

程序排程

**除錯

程式退出

有同學在群裡聊到編譯器優化的事情,很多時候期望編譯器預設做優化,但是有些場景是希望能繞過的,哪些呢?

這裡舉兩個實實在在的例子。

第乙個,在除錯的時候,如果預設開啟了優化,要關注的某個變數值,用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...