volatile

1.关于 volatile 我觉得这样的解析最容易理解:如果编译器在代码中发现对同一地址的两次访问之间,没有对该地址进行写操作,那么编译器将优化为第一次寻址读该地址时取得的值作为第二次寻址的值,而并不是再做第二次物理上的 I/O 寻址操作。volatile 关键字指示编译器进行强制 I/O 寻址,因为编译器那样的优化,可能并不是我们真正期望的,譬如那个地址上连接着一个传感器上的寄存器,那么实际上,可能该寄存器的值是被传感器自身不断刷新的。因此,我们必要要求CPU每次都进行 I/O 操作。2.Why Use Volatile?The reason to use volatile is to ensure that the compiler generates code to re-load a data item each time it is referenced in your program. Without volatile, the compiler may generate code that merely re-uses the value it already loaded into a register.Volatile advises the compiler that the data may be modified in a manner that may not be determinable by the compiler. This could be, for example, when a pointer is mapped to a device's hardware registers. The device may independently change the values unbeknownst to the compiler.Do you volatile? should you?--by Dr. Kevin P. Dankwardt原文链接 http://www.linuxdevices.com/articles/AT5980346182.html3.volatile 跟以前的 register 相反. register 告诉编译器尽量将变量放到寄存器中使用, 而volatile 强制将更改后的值写回内存(无论是cache还是内存). 如果不写回内存, 对于一些全局共享的变量, 可能导致不一致问题.volatie 只是编译器优化功能的关键字4.volatie变量和cache没有关系,只和内存有关系。简单点说就是每次操作前从内存取值有volatie修饰的变量,每次操作时遵循下面动作:从内存取值 ---> 放入寄存器 ----> 操作 ----> 写回内存没有volatie修饰的变量,操作可能 遵循(可能就是不是所有情况都如此):从内存取值 ---> 放入寄存器 ----> 第一次操作 -----> 第二次操作(此时仍操作寄存器中的值) …… ----> 第N次操作 ----> 写回内存举个例子论述两者关系:int volatie i; //全局变量,在其它地方会被修改while ( i){do_somethings( ) ;}如果i没有被volatie修饰,当while循环执行时,另一段程序并发的执行了i= 0, 这个循环仍不会退出,因为每次循环都是检查寄存器中的值。如果有volatie修饰,那么循环结束,因为循环每次检查i的时候,会先从内存把i读入寄存器,这个时候i在其它地方被赋0,则循环结束。5.这么想就明白了.编译器在进行对源码编译过程中,通常会对反复使用的变量整个逼本到reg当中从而提高访问速度.由volatile声明的变量,实际上就是通知编译器该变量会以你意想不到的方式被更改,所以你丫别优化我. 那么编译器意想不到的方式有哪几种呢,如下:1.Memory map的硬件寄存器(比如). 状态寄存器是最常见, 你想呀, 硬件修改这变量他会告诉编译器嘛, 不会也没这能力, 那编译器不就傻呵呵的把该变量优化了嘛, 一优化就坏事了, 因为我们读到的都是reg中存储的旧的状态寄存器的值, 而非memory当中最新的状态寄存器值. 抄个定义给你看看: #define rIICSTAT (*(volatile unsigned *)0x54000004) //IIC status2.多线程中被几个线程共享的变量. 线程修改共享变量var会通知编译器嘛,不会也没这能力,所以线程A使劲读着var在reg中的副本(狗日的编译器优化),读出来1时他好大展鸿图呀,结果读出来的都是0, 而线程B早就把var变量给修改为1了,怪谁呀,只怪没加volatile,加上volatile不早就读memory当中的var新值1了嘛.3.ISR当中用.这个麻烦,需要拿程序举例,俺就不写了.6.一个gcc-volatile的讨论http://gcc.gnu.org/ml/gcc/2007-10/msg00266.html> If you really want all externally-visible accesses to v to be made exactly> as the code directs, rather than allowing gcc to optimise them in any way that> (from the program's POV) it's just the same 'as-if' they had been done> exactly, make v volatile.That is not enough. Apart from the lack of ISO semantics for volatile,typically a compiler will take volatile as a hint to not holdvalues of the variable in a register.On a multi-processor, this is not enough, because each CPUmay still hold modified values in separate caches.Perhaps gcc actually puts a RW barrier to forcecache synchronisation on every volatile access..this seems rather expensive and very hard to do sinceit is very dependent on the actual box (not just theprocessor). Some processor caches might require externalelectrical signals to synchronise, for example. This isquite possible if you have multiple CPU boards in a box.But I don't actually know what gcc does, although I guessit does nothing. The OS has to do the right thing herewhen a mutex is locked etc, but the code for that isprobably in the kernel which is better able to managethings like cache synchronisation than a compiler.c/c++没有多线程的概念,没有一个明确的memory model,volatile不能保证共享变量在多线称间同步,应该使用明确的lock。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值