▲ 点击上方蓝字关注我们,不错过任何一篇干货文章!工欲善其事,必先利其器,对嵌入式工程师来说,嵌入式编译器是不可或缺的神兵利器,它被人冠以“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)|出品
ua1vw2yohsp64016939006.png
RTOS中,GCC没打过IAR
wpgnjtsfpfe64016939106.png
现如今,“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不开源、不免费、不可控,但是它会更代码执行效率更高。
od4ch2otuxp64016939207.png
ArmCC中断响应汇编
pqhprgfxxvt64016939308.png
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
猜你喜欢:
WiFi6+蓝牙+星闪,三合一开发板,真香!
Github上热门 C 语言项目汇总!
嵌入式,可测试性软件设计!
一些低功耗软件设计的要点!
嵌入式 C 保护结构体的方式
实用 | 10分钟教你通过网页点灯
谈谈嵌入式软件的兼容性! |