YVR18資料關注點7:AutoFDO@ARM
演講416做了一個關於在ARM平臺上使用perf的介紹,除了有一些基本的如何使用perf的知識以外,特別介紹了使用基於perf使用CoreSight(注1)等ARM專有功能。
但我比較感興趣的是裡面關於AutoFDO的例子。
所謂FDO,是gcc等編譯器的一個特性,Feedback-Directed Optimization(link)。編譯程式有一個很難處理的問題是如何判斷程式碼的分支是跳轉還是不跳轉(這東西影響流水線),晶片OoO(Out-of-Order,預測執行)設計很大程度上也是為了解決這個問題。FDO的方法是編譯器先編譯一個Instrumented版本(加通過gcov技術),執行一次,收集到所有的跳轉資料了(在.gcda檔案中),用這個資料來判斷跳轉的可能性是怎麼樣的,然後再用這個資料生成一個優化過的版本,正式使用。
下面是我在我的桌面機器上用這個技術執行gcc的例子的結果。編譯過程如下:
BN=bubble ALL=$(BN)_o0 $(BN)_o3 $(BN)_fdo all: $(ALL) $(BN)_o0: $(BN).c gcc $< -o $@ $(BN)_o3: $(BN).c gcc -O3 $< -o $@ $(BN)_inst: $(BN).c gcc -fprofile-generate $< -o $@ $(BN).gcda: $(BN)_inst ./$(BN)_inst $(BN)_fdo: $(BN).c $(BN).gcda gcc -O3 -fprofile-use=$(BN).gcda $< -o $@ test: $(ALL) ./$(BN)_o0 ./$(BN)_o3 ./$(BN)_fdo clean: rm -f $(ALL) $(BN)_inst *.gcda *.gcno .PHONY: test clean
結果如下:
./bubble_o0 Bubble sorting array of 30000 elements 3060 ms ./bubble_o3 Bubble sorting array of 30000 elements 1477 ms ./bubble_fdo Bubble sorting array of 30000 elements 1161 ms
對於這種演算法類的程式(段),還是很有效果的。
FDO的最大缺點是代價很高,你沒法拿一個-fprofile的版本直接到工作環境裡面去用。但perf是沒有這個問題的。所以,gcc還推出一個特性,叫AutoFDO(應該是Google提出來的,這個東西特別適合資料中心),它是用perf資料生成需要的.gcda檔案,這樣我們很容易在工作環境中拿到對應的資料了。
AutoFDO依賴於PMU的這個特性:PERF_SAMPLE_BRANCH_STACK。簡單說,就是branch事件要分taken和untaken獨立記錄。現在很多ARM SoC不支援這個特性。演講416提出的解決方案是用CoreSight來解決這個問題。
我要想要的解決方案不是這樣的,我想要的解決方案是推動所有伺服器SoC供應商把這個作為標準特性來提供。
【注1】CoreSight是一個硬體跟蹤器,自帶記憶體,內建在SoC中(很多ARM SoC實現中都有),它可以直接從硬體的角度跟蹤事件,我感覺對晶片設計師的作用大於軟體設計師。用法和不同的perf record/report的模式基本上是一樣的。