volatile与编译器代码优化浅析

转载自:http://blog.chinaunix.net/uid-24641004-id-3395896.html


Volatile有什么用?

最近写ARM9的裸板C语言代码,比如说我想表示到GPBCON的地址的内容,我们往往会这样写:

  1. #define GPBCON (*(volatile unsigned int*)0x56000010)

 

这里的volatile关键字就是要告诉编译器,这个变量时经常改变的,而且编译时不要进行代码优化,所以每次读写的时候都要到它所在的地址去读取。这个对于一个寄存器地址来说非常重要,如果我们没有声明,很可能会给编译器进行编译优化,编译器生成的代码将不会是0x56000010这里读取,那么,如果我们的寄存器的状态变化了,我们的程序读取的地址却不是这个,那么就会出错。

关于编译器优化

为了提高运行效率,攻城湿们可是费尽心机地把代码优化,把程序运行时存取速度优化。一般,分为硬件优化和软件优化。硬件优化,流水线工作,详细可以参考《计算机组成原理》。

软件优化,一部分是程序猿们做的代码优化(前提你得有优化的思路和能力),还有一部分就是我们的编译器优化了。

现代的编译器经过那么多年的发展,已经比较成熟,把很多余的变量忽略掉,让代码的效率更高。而在默认情况下,编译器都会对代码进行优化,为了提高存取变量的速度,会把一些变量在寄存器里存取,而不是在内存里存取了,那这样CPU在自己家里拿东西当然比从内存那里拿东西要快得多。这样的情况一般我们在PC上写些入门级练习程序一般体验不到,但是对于学嵌入式,单片机的同学来说就是个不可忽视的问题。

如果写裸板程序时,我们对板的寄存器操作是不可避免的,但是如果我们没有用到volatile,那么这个板的寄存器的内容也被编译器默认编译到CPU的寄存器里读取,那么如果寄存器的状态发生改变了,我们能读到正确的状态吗?答案当然是否定的,我们这样只能读到CPU寄存器里的状态,而这个状态只是编译时就存在的,而CPU又没有再次读取内存了,所以这个状态是不变的,这是多么可怕的情况啊,我们触发一个外部中断都没有反应···

而是用volatile之后,编译器编译时就会明白,哦,这个变量很特殊,一定要到原来的地址去存取,不用把它优化,放在CPU寄存器里存取而是每次存取都从它原来的地址去读取。

那我们总结一下,什么时候会需要用到volatile这个关键字:

1 并行设备的硬件寄存器(如:状态寄存器) 

2 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables) 

3 多线程应用中被几个任务共享的变量  

也就是说,状态要经常变化的,为了防止我们编译优化而导致的存取的数据不同步的问题,这时我们就需要用到!

本文只是简单地介绍,如果想了解更多关于编译器具体怎么优化请看以下链接:

volatile关键字的作用:防止变量被编译器优化

http://witmax.cn/volatile.html

编译器优化

http://www.cnblogs.com/dayouluo/archive/2005/12/25/304455.html

浅析代码优化

http://www.cnblogs.com/yanlingyin/archive/2012/02/04/Programoptimization.html

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值