分享

开源嵌入式编译器,没想象中那么好?

 知芯世界 2024-09-10 发布于黑龙江

工欲善其事,必先利其器,对嵌入式工程师来说,嵌入式编译器是不可或缺的神兵利器,它被人冠以“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)
131.13
90.03
95.54
98.54
97.45
87.84kB
85.47
编译用时(秒)
7.23
7.52
7.99
8.3
8.4
8.17
7.64
ARMCC  V5.06
bin大小(KB)
77.18
64.49
61.19
61.44
- -
- -
- -
编译用时(秒)
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./the-hidden-costs-of-open-source-compilers
[2]https://www.zhihu.com/question/26864086/answer/280900095
[3]https://club./ask/article/866813c0a2efd608.html
[4]https://www.bilibili.com/video/BV18h4y1v7yR

· END ·





欢迎将我们设为“星标”,这样才能第一时间收到推送消息。

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多