background image

C 语言中 volatile 关键字的作用

一.前言

1.编译器优化介绍:

由于内存访问速度远不及 CPU 处理速度,为提高机器整体性能,在硬件上引入硬件

高速缓存 Cache,加速对内存的访问。另外在现代 CPU 中指令的执行并不一定严格按照顺

序执行,没有相关性的指令可以乱序执行,以充分利用 CPU 的指令流水线,提高执行速

度。以上是硬件级别的优化。再看软件一级的优化:一种是在编写代码时由程序员优化,

另一种是由编译器进行优化。编译器优化常用的方法有:将内存变量缓存到寄存器;调整

指令顺序充分利用 CPU 指令流水线,常见的是重新排序读写指令。对常规内存进行优化

的时候,这些优化是透明的,而且效率很好。由编译器优化或者硬件重新排序引起的问题

的解决办法是在从硬件(或者其他处理器)的角度看必须以特定顺序执行的操作之间设

置内存屏障(memory barrier),linux 提供了一个宏解决编译器的执行顺序问题。

void Barrier(void)

这个函数通知编译器插入一个内存屏障,但对硬件无效,编译后的代码会把当前

CPU 寄存器中的所有修改过的数值存入内存,需要这些数据的时候再重新从内存中读出。

2.volatile 总是与优化有关,编译器有一种技术叫做数据流分析,分析程序中的变量

在哪里赋值、在哪里使用、在哪里失效,分析结果可以用于常量合并,常量传播等优化,

进一步可以消除一些代码。但有时这些优化不是程序所需要的,这时可以用 volatile 关键

字禁止做这些优化。

二.volatile 详解:

1.volatile

” 

的本意是 易变的 因为访问寄存器要比访问内存单元快的多,所以编译器一

般都会作减少存取内存的优化,但有可能会读脏数据。当要求使用 volatile 声明变量值的

时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数

据。精确地说就是,遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行

优化,从而可以提供对特殊地址的稳定访问;如果不使用 valatile,则编译器将对所声明

的语句进行优化。(简洁的说就是:volatile 关键词影响编译器编译的结果,用 volatile 声

明的变量表示该变量随时可能发生变化,与该变量有关的运算,不要进行编译优化,以

免出错)

2.看两个事例: