volatile关键字

volatile是用于向编译器传递某种信息的关键字。这种信息可以限制编译器对代码的优化,以免这些优化造成意想不到的后果。

一、编译器优化

对于现代编译器来说,常见的优化行为包括优化内存访问、加大并行程度等。

优化内存访问主要是减少对内存的访问次数。由于RAM的速度远远慢于CPU的执行速度,因此,在硬件层面上引入了cache和寄存器以减少访存,提高对指令和数据的访问速度。

加大指令并行程度就是经过编译器判断不会引起问题的条件下,调整指令的执行顺序,以尽可能多的利用CPU的指令流水线。

通常情况下,编译器的优化可以带来性能的提升,但是有些条件下则会造成错误。

二、volatile的作用

volatile的字面意思是“不稳定的,易变的”。它会通知编译器,声明为volatile的变量的值可能随时改变,不要对这个变量的访问进行优化。

具体来说,主要有下面几种情况。

1、不要优化掉对volatile的访问

int i;

int k;
int j;
.......
i=k;
i=j;
在上面的代码中,编译器可能会直接优化掉i=k,只保留i=j;如果对i的赋值有特殊含义(比如i代表某个硬件设备的指令寄存器),那么上面的优化就会造成错误。

volatile int i;

int k;
int j;


i=k;
i=j;
2、不要做变量的值不会改变的假设
编译器可以利用“数据流分析”技术,确定变量在那里赋值、在哪里使用、在哪里销毁,并依据此对变量的访问进行优化。例如,如果变量在某次被访问的时候加载到cache或者寄存器中,并且在当前线程中下一次访问之前没有修改过(编译器也只能确定当前线程的访问情况),那么下一次访问就会直接冲寄存器或者cache中获取。使用volatile后,每次对变量的访问都会从内存中取,而不会将其缓存在cache或者寄存器中。

但是,如果变量的值可能被另外的线程修改(编译器无法得知是否会被其他线程修改),那么寄存器或者cache中的数据就是过时的。这就有可能造成错误。

int flag=false;

while(!flag);

doSomething();
当flag被修改为true是,变回调用doSomething();flag由另外的线程修改。

但没有将flag声明为volatile的话,可能会出现下面的情况:对flag进行第一次访问时,将flag加载到寄存器中,由于在当前线程中没有对flag进行修改,之后每次判断,很有可能直接从寄存器中独出flag的值进行判断。毫无疑问这会造成死循环。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值