【问题背景】

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编译选项的一个过优化问题及其解决方法相关推荐

  1. '操作必须使用一个可更新的查询'解决方法

    原文:'操作必须使用一个可更新的查询'解决方法 当我们用ASP执行修改数据库记录操作时常会遇到以下问题 错误类型: Microsoft OLE DB Provider for ODBC Drivers ...

  2. oracle数据库sid已存在,Oracle SID在本机下已经存在,请指定一个不同的SID”的解决方法...

    Oracle SID在本机上已经存在,请指定一个不同的SID"的解决办法 windows 系统: 1. 开始->设置->控制面板->管理工具->服务 停止所有Orac ...

  3. Sublime Text 4 编译 LaTeX文档后总是新打开一个 Sublime Text 4 的解决方法

    Sublime Text是一个优秀的文本编辑器,我喜欢用它来编辑与编译LaTeX文档,用到的插件是LaTeXTools,网络上的配置方法很多,但有一个问题始终困扰着我,使我差点放弃这种TeX文档编辑方 ...

  4. “远程主机强迫关闭了一个现有连接”问题的解决方法之一

    出现的现象 Android studio模拟器打不开,提示:"远程主机强迫关闭了一个现有连接" 解决办法:关闭网络,重新运行即可

  5. 双显卡双显示器的情况下,一个显示器清晰一个显示器模糊的情况解决方法

    先说结论:很有可能是接口的原因,比如你一个用的HDMI一个用的VGA(显卡上的接口),而你接VGA的那个显示器又分辨率比较高,这个时候最好用显卡上的HDMI口(或者DP,总之用高级一点的接口,最好不要 ...

  6. pythongetattribute_对Github上Python开源项目进行分析时遇到的一个AttributeError的解释及其解决方法。...

    最近在分析Github的Python开源项目时候遇到了一些问题,直接上传代码段: import requests import pygal from pygal.style import LightC ...

  7. php输出excel表格乱码和第一个0不显示的解决方法(详细)

    而关于php的也有,但是大多都是用phpExcel导出的方法或者spreadsheet等类或者控件之类的导出方法,而我所在维护的系统却用很简单的方法,如下,网上很少有讲如何设置要导出数据的EXcel格 ...

  8. IIS发布网站出现“未能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项。”的解决方法...

    有三种解决方法,推荐使用第二种: 1. 在x64的机子上使用了错误版本的System.Data.SQLite.dll,即x86,需要安装合适版本的System.Data.SQLite.dll. 2. ...

  9. iview-admin二级目录只有一个时变成一级目录解决方法

    一开始我以为是获取菜单时过滤了,检查过util.js的getMenuByRouter方法发现返回的数组没毛病 然后开始找显示目录的文件,果然是显示时过滤的 然后对side-menu.vue文件修改 然 ...

最新文章

  1. Android开发技术周报176学习记录
  2. 银光甘特图/日历图/排程控件GTP.NET for Silverlight介绍及正版下载
  3. Mysql索引会失效的几种情况分析
  4. 潘多拉开发板STM32L475之LCD与GBK(含GB2312)字体显示
  5. 12无法使用otg_ios设备该如何选择U盘,以及U盘日常使用技巧
  6. xml方式实现aop-切点表达式的写法
  7. 计算机学生工学交替报告书,工学交替学生守则
  8. C++经典书籍和相关内容
  9. Oracle 10g 完全卸载(windows平台和linux平台)
  10. 我的世界服务器开启就停止运行,我的世界怎么停止时间
  11. 服务器机柜内手机信号,手机信号强度是什么
  12. Eclipse中添加Android系统jar包
  13. 数据科学高级分析 (Data science advanced analytics)
  14. 将根据时间戳增量数据方案修改为根据批次号增量数据方案
  15. sql 二进制文件的导入导出
  16. 2013年最具有技术影响力原创图书评选
  17. imx8开发之~源码编译
  18. c语言 众数,C语言实现查找一组数中的众数
  19. 赵小楼《天道》《遥远的救世主》深度解析(9)肖亚文的“小心思和小算计”
  20. 幂乘法求最大特征值和特征向量

热门文章

  1. 卡车图像分离车头、车厢、车轮
  2. Hbuilder引用css文件无效
  3. JavaScript Sanitizer API:原生WEB安全API出现啦
  4. orangepi3 lts动态加载驱动
  5. (java毕业设计源码)基于java(springboot)简历系统源码成品
  6. 男人们必知的人生定律~(其实女人也得知道)
  7. docker安装个人云盘可道云kodbox
  8. pyecharts案例 超市4年数据可视化分析01
  9. 如何把一个字符串转换成整数
  10. 考研专业课微机原理和c语言,哪个学校自动化考研是考微机原理????