Chinaunix首页 | 论坛 | 博客
  • 博客访问: 986266
  • 博文数量: 327
  • 博客积分: 9995
  • 博客等级: 中将
  • 技术积分: 4319
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-25 11:21
文章存档

2011年(31)

2010年(139)

2009年(157)

我的朋友

分类: C/C++

2009-05-28 10:02:19

volatie变量和cache没有关系,只和内存有关系。
简单点说就是每次操作前从内存取值
有volatie修饰的变量,每次操作时遵循下面动作:
从内存取值 ---> 放入寄存器 ----> 操作 ---->写回内存
没有volatie修饰的变量,操作可能遵循(可能就是不是所有情况都如此):
从内存取值 ---> 放入寄存器 ----> 第一次操作 -----> 第二次操作(此时仍操作寄存器中的值) …… ---->第N次操作 ---->写回内存

---------------------------------------------------------------------

这里说的“cache”不是通常意义上的缓存,即CPU内部缓存或磁盘缓存等。它是一种更加广义上的缓存概念:以提高访问效率为目的,把数据或处理后的数据保存起来加以利用的现象都可以称为缓存。

题目中的缓存实际上指的是寄存器,与CPU缓存无关。编译器的优化可以把本来在内存中进行访问的数据装入(缓存)到寄存器中以提高访问效率。然而这种优化在一些情况下可带来问题;此时,应该用 volatile 告诉编译器不要进行这种优化以避免问题的出现。

---------------------------------------------------------------------

编译器在进行对源码编译过程中,通常会对反复使用的变量整个优化到reg当中从而提高访问速度.由volatile声明的变量,实际上就是通知编译器该变量会以你意想不到的方式被更改,所以你丫别优化我. 那么编译器意想不到的方式有哪几种呢,如下:

1.Memory map的硬件寄存器(比如). 状态寄存器是最常见, 你想呀, 硬件修改这变量他会告诉编译器嘛, 不会也没这能力, 那编译器不就傻呵呵的把该变量优化了嘛, 一优化就坏事了, 因为我们读到的都是reg中存储的旧的状态寄存器的值, 而非memory当中最新的状态寄存器值. 抄个定义给你看看: #define rIICSTAT (*(volatile unsigned *)0x54000004) //IIC status

2.多线程中被几个线程共享的变量. 线程修改共享变量var会通知编译器嘛,不会也没这能力,所以线程A使劲读着var在reg中的副本(狗日的编译器优化),读出来1时他好大展鸿图呀,结果读出来的都是0, 而线程B早就把var变量给修改为1了,怪谁呀,只怪没加volatile,加上volatile不早就读memory当中的var新值1了嘛.

3.ISR当中用.这个麻烦,需要拿程序举例,俺就不写了.

再有, 讨论volatile就讨论volatile. 跟cache有嘛关系, cache是不可见的...不可见的...我看不着~~~

---------------------------------------------------------------------
举个例子论述两者关系:
int volatie i; //全局变量,在其它地方会被修改

while (i)
{
do_somethings();
}
如果i没有被volatie修饰,当while循环执行时,另一段程序并发的执行了i=0, 这个循环仍不会退出,因为每次循环都是检查寄存器中的值。
如果有volatie修饰,那么循环结束,因为循环每次检查i的时候,会先从内存把i读入寄存器,这个时候i在其它地方被赋0,则循环结束。

阅读(845) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~