volatile的作用

news/2024/7/10 5:46:13 标签: 编译器, 优化, 任务调度, 任务, service, 存储
 

volatile的本意是“易变的”

由于访问寄存器的速度要快过RAM,所以编译器一般都会作减少存取外部RAM的优化。比如:

static int i=0;

int main(void)
{
...
while (1)
{
if (i) dosomething();
}
}

/* Interrupt service routine. */
void ISR_2(void)
{
i=1;
}

程序的本意是希望ISR_2中断产生时,在main当中调用dosomething函数,但是,由于编译器判断在main函数里面没有修改过i,因此
可能只执行一次对从i到某寄存器的读操作,然后每次if判断都只使用这个寄存器里面的“i副本”,导致dosomething永远也不会被
调用。如果将将变量加上volatile修饰,则编译器保证对此变量的读写操作都不会被优化(肯定执行)。此例中i也应该如此说明。

一般说来,volatile用在如下的几个地方:

1、中断服务程序中修改的供其它程序检测的变量需要加volatile;

2、多任务环境下各任务间共享的标志应该加volatile;

3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;

另外,以上这几种情况经常还要同时考虑数据的完整性(相互关联的几个标志读了一半被打断了重写),在1中可以通过关中断来实
现,2中可以禁止任务调度>任务调度,3中则只能依靠硬件的良好设计了。

volatile 的含义
volatile 总是与优化有关,编译器有一种技术叫做数据流分析,分析程序中的变量在哪里赋值、在哪里使用、在哪里失效,分析结果可以用于常量合并,常量传播等优化,进 一步可以死代码消除。但有时这些优化不是程序所需要的,这时可以用volatile关键字禁止做这些优化,volatile的字面含义是易变的,它有下面 的作用:

1 不会在两个操作之间把volatile变量缓存在寄存器中。在多任务、中断、甚至setjmp环境下,变量可能被其他的程序改变,编译器 自己无法知道,volatile就是告诉编译器这种情况。

2 不做常量合并、常量传播等优化,所以像下面的代码:
volatile int i = 1;
if (i > 0) ...

if的条件不会当作无条件真。

3 对volatile变量的读写不会被优化掉。如果你对一个变量赋值但后面没用到,编译器常常可以省略那个赋值操作,然而对Memory Mapped IO的处理是不能这样优化的。

前面有人说volatile可以保证对内存操作的原子性,这种说法不大准确,其一,x86需要LOCK前缀才能在SMP下保证原子性,其二,RISC根本不能对内存直接运算,要保证原子性得用别的方法,如atomic_inc。

对于jiffies,它已经声明为volatile变量,我认为直接用jiffies++就可以了,没必要用那种复杂的形式,因为那样也不能保证原子性。

你可能不知道在Pentium及后续CPU中,下面两组指令

inc jiffies
;;
mov jiffies, %eax
inc %eax
mov %eax, jiffies

作用相同,但一条指令反而不如三条指令快。

http://www.niftyadmin.cn/n/841529.html

相关文章

AC日记——租用游艇 洛谷 P1359

题目描述 长江游艇俱乐部在长江上设置了n 个游艇出租站1&#xff0c;2&#xff0c;…&#xff0c;n。游客可在这些游艇出租站租用游艇&#xff0c;并在下游的任何一个游艇出租站归还游艇。游艇出租站i 到游艇出租站j 之间的租金为r(i,j),1<i<j<n。试设计一个算法&…

Java反射解析XML字符串并封装到指定的JavaBean(比较复杂)

文章来源&#xff1a; http://my.oschina.net/realfighter/blog/349894

分布式MySQL集群方案的探索与思考

背景 数据库作为一个非常基础的系统&#xff0c;任何一家互联网公司都会使用&#xff0c;数据库产品也很多&#xff0c;有Oracle、SQL Server 、MySQL、PostgeSQL、MariaDB等&#xff0c;像SQLServer/Oracle 这类数据库在初期可以帮业务搞定很多棘手的事情&#xff0c;我们可以…

barrier(wmb,mb,rmb)和cache coherence

http://www.linuxforum.net/forum/gshowflat.php?Cat&BoardlinuxK&Number428239&page5&viewcollapsed&sb5&oall&fpart 注: 这里的barrier 指的是wmb, rmb, mb. 一 直找不到合适的资料说明barrier和 Cache coherence 之间的关系. 在<<ldd>…

你需要了解自动化运维的设计思想

传统运维的弊端&#xff1a; 1.由人来发起运维事件&#xff0c;运维人员被动、效率低。 2.系统异构性大&#xff0c;缺乏高效的运维流程。 3.随着云计算大数据的爆发带来更大的困难&#xff0c;极度缺乏一套高效的运维工具。 由于这些问题的存在&#xff0c;自动化应该遵循四化…

如何将tomcat控制台输出的内容直播用日志文件保存起来(Log4j)

文章来源&#xff1a;http://bbs.csdn.net/topics/320167909 在项目中的classes 中新建立一个log4j.properties文件即可&#xff1b; 在实际编程时&#xff0c;要使Log4j真正在系统中运行事先还要对配置文件进行定义。定义步骤就是对Logger、Appender及Layout的分别使用。…

Linux下的sniffer工具--Tcpdump的安装和使用

在如今众多的黑客技术中&#xff0c;嗅探器(sniffer)是最常见&#xff0c;也是最重要的技术之一。用过windows平台上的sniffer工具(例如&#xff0c; netxray和sniffer pro软件)的朋友可能都知道&#xff0c;在共享式的局域网中&#xff0c;采用sniffer工具简直可以对网络中的所…

高手详解SQL性能优化十条经验

转载地址&#xff1a;http://database.51cto.com/art/200904/118526.htm 1.查询的模糊匹配 尽量避免在一个复杂查询里面使用 LIKE %parm1%—— 红色标识位置的百分号会导致相关列的索引无法使用&#xff0c;最好不要用. 解决办法: 其实只需要对该脚本略做改进&#xff0c;查询速…