開源嵌入式編譯器,沒想象中那麼好?

▲ 點擊上方 藍字 關注我們,不錯過任何一篇乾貨文章!

工欲善其事,必先利其器,對嵌入式工程師來說,嵌入式編譯器是不可或缺的神兵利器,它被人冠以“C語言翻譯官”的名號。 由於C語言歷史悠久,早期沒有規範,整個計算機產業也都處於拓荒的年代,所以就涌現了很多款C語言編譯器。

根據EEWorld的調研,嵌入式工程師比較青睞的嵌入式編譯器主要包括Keil(ArmCC)、IAR、GCC、AVR GCC、CLion、Clang、green hills、TI的CSS、ADI的Visual DSP++。不過,隨着嵌入式開發格局逐漸穩固,Keil、IAR、GCC成爲嵌入式編譯器三巨頭,基本大部分嵌入式產品都有其身影。

尤其是GCC,作爲一個完全開源的編譯器,很多MCU廠商的IDE都由它改寫而來。但最近一段時間,業界出現不同的聲音,表示“開源纔是最貴的”,這些編譯器在開源背後潛藏許多隱形成本。

付斌|作者

電子工程世界(ID:EEWorldbbs)|出品

RTOS中,GCC沒打過IAR

現如今,“C/C++與RTOS結合使用”是嵌入式軟件開發的黃金範式,所以在嵌入式領域,判別編譯器好不好用,那一定是在RTOS上好用。

根據著名嵌入式Jacob Beningo的測試,使用IAR編譯時,RTOS指標性能比使用GCC編譯時要好得多。根據公制測試,結果略有不同,但通常要好20~40%。以其中一個示例結果爲例,該示例將IAR指標結果除以 ThreadX(Eclipse ThreadX)的GCC指標結果。

RTOS測試 ThreadX

基準測試 74%

系統調度 3%

內存分配測試 28%

消息處理 41%

搶佔式調度 19%

同步處理 32%

也許會有人說,編寫代碼的質量決定了性能好壞。這句話確實沒錯,人們可以花費大把時間,細緻地優化代碼,但這不意味着開發時間更長,開發成本更高?

比如說,一些IoT項目工期比較短,有時候如果沒有來得及去優化,那可能GCC處理時間會增加20%,並且讓電池更費電。又或者,GCC編譯的代碼可能體積也會更大,這時候,內存從120MHz就需要變相升級到200MHz,這幾塊錢的差距,就會讓產品成本大幅度增加。

GCC的確是行業一個福音,但相比商業編譯器,也許它本身也存在一定額外的隱形開銷。看目前RTOS抑或是開源RTOS本身也是附帶工具鏈的,大部分則只支持GCC,卻不支持商業編譯器IAR,這種情況導致客戶選擇面變窄。

Keil比GCC編譯文件,更小

雖然Keil目前已經包括五種版本,其中不乏全免費的教育版,而且STM32之類的MCU使用Keil也是免費的,但如果做一些很深入的開發工作,Keil本身還是需要付費的。所以它實質上還是算在商業編譯器範疇內。

在工程師羣裡,很多人都提到一個話題,就是Keil的ArmCC編譯器很神。那麼實際情況如何呢?

根據工程師的測試,可以得知,GCC的編譯速度最快(Keil和VisualGDB都開啓多線程編譯的)。而bin體積最小的是ArmCC V5。代碼的執行效率沒有測。

而ArmCC V5和V6對比,編譯用時差異不大,手動掐表可以認爲是誤差範圍內。但是bin體積V5比V6小很多。

優化選項

O0

O1

O2

O3

Ofast

Os

Oz

ARMCC V6.9

bin大小(KB)

87.84kB

編譯用時(秒)

7.23

7.52

7.99

8.3

8.4

8.17

7.64

ARMCC V5.06

bin大小(KB)

編譯用時(秒)

7.93

8.25

8.15

9.68

GCC 7.2

bin大小(KB)

176

135

136

144

129

編譯用時(秒)

3.49

3.63

3.68

4.12

3.96

爲什麼有時候會出現文件大小區別的情況?有工程師也曾經遇到過GCC編譯bin文件比ArmCC大的情況,通過捋順代碼,發現有些原廠本身做了一些優化工作,所以實際上這本身也就節省了工程師優化的時間。

也有工程師表示,Keil有Keil的優勢,GCC有GCC的優勢,二者大多數情況下不可兼得;Keil(ArmCC)編譯對Arm芯片有天然的優勢,無論從代碼性能和代碼尺寸都有更佳的表現;GCC優勢在於開源,利於折騰。

也有工程師在m0上做了實驗,使用同樣的代碼觸發pendsv中斷,ArmCC響應時間爲68clocks,gcc響應時間爲78clocks。他表示,雖然ArmCC不開源、不免費、不可控,但是它會更代碼執行效率更高。

ArmCC 中斷響應彙編

GCC中斷響應彙編

用誰,工程師各持己見

蘿蔔青菜各有所愛,不論如何測試,工程師總是有自己的偏好。因爲公司需求不同,對於Flash、執行速度、交付等要求不同,使用不同編譯器都有不同的結果。

喜歡Keil的,在實際體驗中,ac6的Osize優化特別猛,性能稍微弱一丟丟,但是體積特別小,其它編譯器都比不過,同樣的程序比gcc能小四分之一。但它讓人又愛又恨,就比如MDK AC6曾經出現過調試到處亂跳的問題,不過商業版本有所改善,或者說MDK經常把if-else結構優化成IT彙編指令,在反彙編窗口中打的斷點都命中了實際確不會執行。很多人表示,習慣了。

有人更喜歡用IAR,IAR不僅比Keil便宜很多,而且還內置了misra靜態檢查工具,很方便。

有傳統GCC派,gdb調試Vscode編輯,在Linux系統下編譯很香,有些老闆不在意Flash的情況下,可以有最快的交付速度。也有Clion、Clang之類的新派。

那麼,你怎麼看待不同編譯器之間的差異問題,你又會選用什麼編譯器?

參考文獻

[1]https://www.embedded.com/the-hidden-costs-of-open-source-compilers

[2]https://www.zhihu.com/question/26864086/answer/280900095

[3]https://club.rt-thread.org/ask/article/866813c0a2efd608.html

[4]https://www.bilibili.com/video/BV18h4y1v7yR

歡迎將我們設爲“星標”,這樣才能第一時間收到推送消息。

領領取自動駕駛、輔助駕駛等方面免費資料包!

掃碼添加小助手回覆“進羣”

和電子工程師們面對面交流經驗