关于O2编译选项的一个过优化问题及其解决方法
【问题背景】
O2编译选项广泛用于嵌入式编程中,可大幅降低CPU耗时。
但优化编译选项级别越高,编译工具链对源代码的指令优化与重排力度越大,最后生成的汇编指令越有可能与编程者预期的逻辑有偏差。
【问题现象】
目前在实际工作中发现O2下循环语句工作异常。实验代码段如下:
代码1
代码1实现的功能是:轮询地址为0xf0000000的数值,一旦数值为1则跳出循环继续进行“其他处理”。
在异构编程中这种写法经常被用于等待某一内存/寄存器的数值发生变化。
但实践发现,上述代码经过O2编译后,实际工作现象为:即使0xf0000000地址内数值为1,也无法跳出循环。这与编程预期严重不符。
【问题根因】
代码1经过O2优化后的汇编文件为:
代码2
从代码2可见,从地址0xf0000000中读取数值的动作只发生了一次,而在循环中未再读取,只是单纯地将第一次读取到的数值与立即数进行比对。故即使0xf0000000地址中的数值变化为了1,也无法跳出循环。
另外,通过去除优化选项作为对照组来确定问题根因为“启用了O2”,此时代码1的汇编文件为:
代码3
从代码3可见,在循环中每次都先读取0xf0000000地址中的数值后再与立即数进行比对,故在不启用O2的情况下,汇编指令的逻辑与编程者预期一致。
【解决方案】
通过上述分析可知问题根因为:启用了O2。但不使用O2是不现实的,尤其是对于CPU不强的平台来讲。
面对这种问题,可以在全部代码处于O2优化的情况下,通过使用volatile关键字来保护某些代码,避免编译器对其进行优化,即将代码1中的第3行改为:
unsigned int volatile *addr = 0xf0000000;
此时代码1的汇编文件为:
代码4
由代码4可见,在每次做比对之前,都会从0xf0000000中重新读取数值,符合预期逻辑。并且代码4比完全不使用优化编译选项的代码3更为精简,耗时更短。
【未解决问题】
目前在交叉编译工具链arm-seev100-linux-gnueabihf-和aarch64-none-linux-gnu-中均存在这个问题,但不确定使用gcc进行编译是否会存在这个问题,故暂不能完全确定是否和编译工具链有关。
关于O2编译选项的一个过优化问题及其解决方法相关推荐
- '操作必须使用一个可更新的查询'解决方法
原文:'操作必须使用一个可更新的查询'解决方法 当我们用ASP执行修改数据库记录操作时常会遇到以下问题 错误类型: Microsoft OLE DB Provider for ODBC Drivers ...
- oracle数据库sid已存在,Oracle SID在本机下已经存在,请指定一个不同的SID”的解决方法...
Oracle SID在本机上已经存在,请指定一个不同的SID"的解决办法 windows 系统: 1. 开始->设置->控制面板->管理工具->服务 停止所有Orac ...
- Sublime Text 4 编译 LaTeX文档后总是新打开一个 Sublime Text 4 的解决方法
Sublime Text是一个优秀的文本编辑器,我喜欢用它来编辑与编译LaTeX文档,用到的插件是LaTeXTools,网络上的配置方法很多,但有一个问题始终困扰着我,使我差点放弃这种TeX文档编辑方 ...
- “远程主机强迫关闭了一个现有连接”问题的解决方法之一
出现的现象 Android studio模拟器打不开,提示:"远程主机强迫关闭了一个现有连接" 解决办法:关闭网络,重新运行即可
- 双显卡双显示器的情况下,一个显示器清晰一个显示器模糊的情况解决方法
先说结论:很有可能是接口的原因,比如你一个用的HDMI一个用的VGA(显卡上的接口),而你接VGA的那个显示器又分辨率比较高,这个时候最好用显卡上的HDMI口(或者DP,总之用高级一点的接口,最好不要 ...
- pythongetattribute_对Github上Python开源项目进行分析时遇到的一个AttributeError的解释及其解决方法。...
最近在分析Github的Python开源项目时候遇到了一些问题,直接上传代码段: import requests import pygal from pygal.style import LightC ...
- php输出excel表格乱码和第一个0不显示的解决方法(详细)
而关于php的也有,但是大多都是用phpExcel导出的方法或者spreadsheet等类或者控件之类的导出方法,而我所在维护的系统却用很简单的方法,如下,网上很少有讲如何设置要导出数据的EXcel格 ...
- IIS发布网站出现“未能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项。”的解决方法...
有三种解决方法,推荐使用第二种: 1. 在x64的机子上使用了错误版本的System.Data.SQLite.dll,即x86,需要安装合适版本的System.Data.SQLite.dll. 2. ...
- iview-admin二级目录只有一个时变成一级目录解决方法
一开始我以为是获取菜单时过滤了,检查过util.js的getMenuByRouter方法发现返回的数组没毛病 然后开始找显示目录的文件,果然是显示时过滤的 然后对side-menu.vue文件修改 然 ...
最新文章
- Android开发技术周报176学习记录
- 银光甘特图/日历图/排程控件GTP.NET for Silverlight介绍及正版下载
- Mysql索引会失效的几种情况分析
- 潘多拉开发板STM32L475之LCD与GBK(含GB2312)字体显示
- 12无法使用otg_ios设备该如何选择U盘,以及U盘日常使用技巧
- xml方式实现aop-切点表达式的写法
- 计算机学生工学交替报告书,工学交替学生守则
- C++经典书籍和相关内容
- Oracle 10g 完全卸载(windows平台和linux平台)
- 我的世界服务器开启就停止运行,我的世界怎么停止时间
- 服务器机柜内手机信号,手机信号强度是什么
- Eclipse中添加Android系统jar包
- 数据科学高级分析 (Data science advanced analytics)
- 将根据时间戳增量数据方案修改为根据批次号增量数据方案
- sql 二进制文件的导入导出
- 2013年最具有技术影响力原创图书评选
- imx8开发之~源码编译
- c语言 众数,C语言实现查找一组数中的众数
- 赵小楼《天道》《遥远的救世主》深度解析(9)肖亚文的“小心思和小算计”
- 幂乘法求最大特征值和特征向量