痞子衡嵌入式:MCUXpresso IDE下设置代码编译优化等级的几种方法
大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是MCUXpresso IDE下设置代码编译优化等级的几种方法。
最近公司芯片设计团队正在开发一款全新的基于 Cortex-M33 内核的芯片,为了保证芯片性能达标,验证团队将 coremark 基准测试程序也当作了一个测试用例,而在 RTL 环境里指定的 C 编译器是标准 GCC,验证团队发现跑出来的 coremark 程序测试结果与 Arm 给的 Cortex-M33 参考值 4.02 CoreMark/MHz 有一定差距,痞子衡参与了这个问题调查。
在 Arm Cortex-M33 官方主页,其备注了 4.02 CoreMark/MHz 参考值来自于 EEMBC 官网上的一款 恩智浦 LPC55S69JBD100 芯片跑出来的结果,页面里备注了跑分结果是在 Arm Clang Compiler v6.12 下开启最高优化等级 -Omax 下得到的,而验证团队用得是 GCC,痞子衡断定问题大概率是由不同编译器优化性能差异引起的,借着这个实际问题,今天痞子衡跟大家聊一聊 MCUXpresso IDE 下编译优化等级设置方法。
- Note:本文使用的 MCUXpresso IDE 软件版本是 v11.6.0_8187。
一、查看MCUX下GCC版本
有朋友可能会觉得奇怪,文章开头里明明聊得是 GCC 下 coremark 跑分问题,为何痞子衡引出了 MCUXpresso IDE?其实 MCUXpresso IDE 是恩智浦推出的免费集成开发环境,其底层编译器就是标准 GCC 工具链,使用 MCUXpresso IDE,我们就不用像使用 GCC 那样手动准备相应 Makefile 去做编译了。
因为我们是借助 MCUXpresso IDE 来测试 GCC 编译优化性能,所以需要了解当前 GCC 版本,可以在 MCUXpresso IDE 安装目录如下路径下找到 GCC 版本信息。执行 arm-none-eabi-gcc.exe -v 命令即可知道其版本,MCUXpresso IDE v11.6 使用得是 GCC v10.3.1。
\MCUXpressoIDE_11.6.0_8187\ide\tools\bin\arm-none-eabi-gcc.exe
\MCUXpressoIDE_11.6.0_8187\ide\tools\lib\gcc\arm-none-eabi\10.3.1
二、GCC支持的优化等级
既然咱们聊得是优化等级设置方法,首先我们得知道 GCC 下支持哪些优化等级,我们可以在 MCUXpresso IDE 安装目录或者 GCC 官网找到用户手册(gcc.pdf),手册里面 Section 3.11 Options that Control Optimization 章节有详细的解释。
\MCUXpressoIDE_11.6.0_8187\ide\tools\share\doc\gcc-arm-none-eabi\pdf\gcc.pdf
https://gcc.gnu.org/onlinedocs/gcc-10.3.0/gcc.pdf
GCC 本身支持非常多的优化策略小项,大概有如下 100 多个,可以在手册里去看每个小项的具体解释,了解了这些小项,我们在编译时当然可以把这些策略参数按需加上去,不过这种方式显然比较繁琐。
GCC 为了化繁为简,将这些策略小项做了分类整理,形成了如下 8 个等级(基于代码大小和运行速度两个方向逐步加档),我们在实际编译时一般直接用这 8 个优化等级即可。
| 优化等级 | 策略解释 |
|---|---|
| -O0 | 不进行任何优化(如果没有指定优化级别,即为此默认设置)。 |
| -O或者-O1 | 在不影响编译速度的前提下,尽量采用一些优化算法降低代码大小和提高可执行代码的运行速度。 -此等级执行了 45 个策略小项。 |
| -O2 | 牺牲部分编译速度,采用几乎所有的目标配置支持的优化算法,用以提高目标代码的运行速度。 -此等级在-O1所有优化策略小项之上增加了 48 个策略小项。 |
| -O3 | 采取很多向量化算法,提高代码的并行执行程度,比如利用现代CPU中的流水线,Cache等,目标是宁愿增加目标代码的大小,也要拼命的提高运行速度。 -此等级在-O2所有优化策略小项之上增加了 16 个策略小项。 |
| -Os | 与-O3有异曲同工之妙,但两者的目标不一样,这个等级是为了尽量的降低目标代码的大小,这对于存储容量很小的设备来说非常重要。 -此等级在-O2所有优化策略小项之上减掉了 6 个策略小项,然后使能了 -finline-functions 策略。 |
| -Ofast | 不会严格遵循语言标准,会针对某些语言启用部分优化,以达到最快的运行速度。 -此等级在-O3所有优化策略小项之上增加了 -ffast-math 和 -fallow-store-data-races 策略。 |
| -Og | 在保持快速编译和良好调试体验的同时,提供合理的优化级别。 |
| -Oz | 比-Os更激进的去降低目标代码的大小,GCC v12.x 之后的版本才引入。 |
三、MCUX下设置优化等级的三种方法
在 MCUXpresso IDE 工程里,我们有三种方法来设置优化等级,分别针对单个函数、单个源文件、整个工程源文件。
3.1 在源文件中设置
第一种优化等级设置方法主要针对单个函数,即使用 __attribute__ 来修饰函数(这其实是 GCC 下通用做法,与 MCUX 关系不大),经过修饰的函数可以不受 MCUXpresso IDE 工程整体优化等级设置影响。
void __attribute__((optimize("O3"))) function(void)
{
...
}
第二种优化等级设置方法主要针对多个相邻函数或者整个源文件,即使用如下 #pragma 组合语句来修饰代码(这也是 GCC 下通用做法,与 MCUX 关系不大),经过修饰的代码也同样不受 MCUXpresso IDE 工程整体优化等级设置影响。
#pragma GCC push_options // 代码作用范围起始处
#pragma GCC optimize("O3") // 代码优化等级设置
void function1(void)
{
...
}
void function2(void)
{
...
}
...
#pragma GCC pop_options // 代码作用范围结尾处
3.2 在IDE选项中设置
第三种优化等级设置方法主要针对工程全部源文件,即在 MCUXpresso IDE 工程选项里 Optimization Level 一栏项目里做切换选择,这里基本上与 GCC v10.3 优化等级定义是一致的,但是缺少了 -Ofast 选项。
四、MCUX下设置-Ofast等级
痞子衡找了一块 MIMXRT595-EVK 开发板(主芯片为 Cortex-M33 内核),在其配套 SDK 里的 hello world 工程基础之上移植了 coremark 程序,在 IAR v9.10 最高优化等级下(High-Size No size constraints)得到了 3.94 CoreMark/MHz 的跑分,这很接近 Arm 基准值,但是在 MCUXpresso IDE 最高优化等级下(-O3)仅得到了 2.76 CoreMark/MHz。
莫非是必须要在 MCUXpresso IDE 下开启 GCC 的最快运行优化等级 -Ofast 才能得到理想 coremark 跑分,但是 MCUXpresso IDE 选项里并没有 -Ofast 怎么办?别着急,刚才工程选项下还有 Other optimization flags 后门,我们在这里手动添加上 -Ofast 比 -O3 多的那两个优化策略小项即可。
重新编译,再跑一次 -Ofast 等级下的 MCUXpresso IDE 工程,发现 coremark 跑分结果并没有比 -O3 等级下有多大提升,想了想虽然跑不到 IAR 上 3.94 CoreMark/MHz 的高分有点不甘心,但是这也很正常嘛,免费的 GCC 编译器如果能达到商业 IAR 编译器那样的效果,那人家商业编译器还怎么收费呢,理解万岁!
至此,MCUXpresso IDE下设置代码编译优化等级的几种方法痞子衡便介绍完毕了,掌声在哪里~~~
欢迎订阅
文章会同时发布到我的 博客园主页、CSDN主页、知乎主页、微信公众号 平台上。
微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。

痞子衡嵌入式:MCUXpresso IDE下设置代码编译优化等级的几种方法的更多相关文章
- 痞子衡嵌入式:恩智浦SDK驱动代码风格检查工具预览版
大家好,我是痞子衡,是正经搞技术的痞子. 接上文 <恩智浦SDK驱动代码风格.模板.检查工具> 继续聊,是的,过去的三天里我花了一些时间做了一个基于 PyQt5 的 GUI 工具,可以帮助 ...
- 痞子衡嵌入式:恩智浦SDK驱动代码风格、模板、检查工具
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家讲的是恩智浦 SDK 驱动的代码风格. 上周痞子衡受领导指示,给 SE 同事做了一个关于 SDK 代码风格的分享.随着组内新人的增多,这样的培训 ...
- 痞子衡嵌入式:大话双核i.MXRT1170之单独在线调试从核工程的方法(IAR篇)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT1170下单独在线调试从核工程的方法(基于IAR). 两年前痞子衡写过一篇<双核i.MXRT1170之Cortex-M ...
- 痞子衡嵌入式:MCUXpresso IDE下在线调试时使用不同复位策略的现象总结
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是MCUXpresso IDE下在线调试时使用不同复位策略的现象总结. 本篇实际上是<IAR在线调试时设不同复位类型可能会导致i.M ...
- 痞子衡嵌入式:MCUXpresso IDE下使用J-Link下载算法在Flash调试注意事项(i.MXRT500为例)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是MCUXpresso IDE下使用J-Link下载算法在Flash调试注意事项. 痞子衡前段时间写过一篇小文<为i.MXRT设计更 ...
- 痞子衡嵌入式:MCUXpresso IDE下添加C++源文件进SDK工程编译的方法
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是MCUXpresso IDE下添加C++源文件进SDK工程编译的方法. 最近有客户反映在MCUXpresso IDE下的SDK工程里添加 ...
- 痞子衡嵌入式:MCUXpresso IDE下SDK工程在Build配置上与IAR,MDK差异
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是MCUXpresso IDE下SDK工程在Build配置上与IAR,MDK差异. 恩智浦 SW 团队每个季度都会公布 SDK.Tool ...
- 痞子衡嵌入式:MCUXpresso IDE下工程链接文件配置管理与自动生成机制
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是MCUXpresso IDE下工程链接文件配置管理与自动生成机制. 痞子衡在 2018 年初写过一个专题 <嵌入式开发文件系列&g ...
- 痞子衡嵌入式:MCUXpresso IDE下将应用程序RW段分散链接的几种方法
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是MCUXpresso IDE下将应用程序RW段分散链接的几种方法. 早期的 MCU 芯片,一般都会嵌入内部 Flash 和 RAM,并且 ...
随机推荐
- C语言学习之我见-memchr()内存查找字符函数
memchr()内存查找字符函数:主要用于从内存中查找自己需要的字符位置. (1)函数原型: void *memchr(const void *_Buf ,int _Val,size_t _MaxCo ...
- JS:object
object:对象 1.对象是拥有属性和方法的数据,也是一个变量,但值有多个,以key-value的形式. 2.对象有继承属性: 每当创建一个对象,对象里面就会有一个原型对象prototype,可以从 ...
- 数字格式化的 js 库
数字格式化的 js 库 Numeral.js,是一个用于格式化数字和处理数字的 js 库. Tip:目前 Star 有 9.2k,5年以前就没有在更新.其文档写得不很清晰,比如它提供了多语言,但如何切 ...
- 搭建uipath
我对windows也不太熟,也是第一次安装Uipath Orchestrator,希望有问题指出一起交流,可以留言,Uipath中文qq交流群:4656303241. 下载镜像 windows ser ...
- Linux yum搭建私有仓库
搭建yum仓库需要两种资源: rpm包 rpm包的元数据(repodata) 搭建好仓库后需要使用三种网络协议共享出来 http或https ftp 范例: 使用http协议搭建私有仓库 (本示例使用 ...
- Python教程:执行cmd命令
我们通常可以使用os模块的命令进行执行cmd 方法一:os.system def system(*args, **kwargs): # real signature unknown "&qu ...
- SpringCloud Gateway微服务网关实战与源码分析-上
概述 定义 Spring Cloud Gateway 官网地址 https://spring.io/projects/spring-cloud-gateway/ 最新版本3.1.3 Spring Cl ...
- 解读Go分布式链路追踪实现原理
摘要:本文将详细介绍分布式链路的核心概念.架构原理和相关开源标准协议,并分享我们在实现无侵入 Go 采集 Sdk 方面的一些实践. 本文分享自华为云社区<一文详解|Go 分布式链路追踪实现原理& ...
- 使用ventoy制作启动盘
先去应用商店下载,非Deepin用户去官网下载Download.Ventoy. 先确认一下自己的系统镜像是否在清单内.(其实不在也没事) 按照使用说明操作Get start.Ventoy,建议配置为G ...
- Linux配置Oracle JAVA环境
1.下载java jdk的安装包 #pwd /usr/local/src 2.解压二进制文件并设置软连接 # tar -xvf jdk-8u241-linux-x64.tar.gz # ln -sv ...