免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2983 | 回复: 6
打印 上一主题 下一主题

volatile关键字 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-08-26 14:01 |只看该作者 |倒序浏览
关于这个限定符,不是很确定。

看了一些文档,说主要是为了防止变量被的读写被编译器优化,保证每次读写这个变量都直接作用到内存,而不在寄存器中操作。

但是我想既然编译器这样优化了,自然是对执行的效率有好处的,为什么还要取消这种优化呢?

是不是只有在多线程环境下,共享变量加上这个关键字才有意义呢?是否就是下面的情况:
//=============
比如全局int a;
thread1修改a为2,但这次只在寄存器中修改,之后发生线程上下文切换,到thre2,thre2读取a的数据就出问题了?
//=============

如果是这样,我想编译的优化就有问题吧,这样的情况编译器应该不会进行优化,那么volatile关键字的存在具体还有什么意义呢?


求高人解释。。

论坛徽章:
3
白羊座
日期:2013-11-05 12:59:14子鼠
日期:2014-01-29 14:14:50戌狗
日期:2014-02-11 16:21:45
2 [报告]
发表于 2011-08-26 14:08 |只看该作者
主要跟硬件驱动程序的编写有关。
硬件可能通过DMA直接访问内存,修改变量的值,这种变化是不会自动反应到CPU缓存中的。

论坛徽章:
0
3 [报告]
发表于 2011-08-26 14:23 |只看该作者
回复 1# xxfihm


    “val是全局变量,val在多线程环境中=>val不会被优化”?
还有通常那些会为信号处理函数改写的全局变量会标记易挥发,譬如
  1. volatile bool g_shutdown = false;
  2. static void sighandler(int signal)
  3. {
  4.         if (signal == SIGINT
  5.                     || signal == SIGTERM)
  6.                 g_shutdown = true;
  7. }
复制代码

论坛徽章:
0
4 [报告]
发表于 2011-08-26 14:39 |只看该作者
本帖最后由 狗蛋 于 2011-08-26 14:41 编辑

优化有很多种。

以前看IBM的一篇文章,奔腾3访问一次主内存可能相当于执行14个加法指令.

于是:
x=100
y=fun()
....
....
print_int(x, y, z)

如果中间没有写过x或者把x传递给可能修改它的函数,那么合格的编译器就应该直接把这个x替换成常量100(而不是执行昂贵的内存读操作)


此外,现代CPU有很多寄存器,上面的y值如果一直没有被修改过,那么它完全可以放在寄存器里,到print_int的时候直接从寄存器中取值——这同样是合格的现代编译器所必须具备的能力。

随便说一句,如果print_int声明为void print_int(const &int, int, int &),那么编译器就可以知道,print_int不会修改传递给它的前两个int参数,但会修改第三个int参数——于是执行print_int之后,x、y仍然可以继续认为没有变化,而z就必须重新从主存读取了。这是const的价值之一,也是不要用强制类型转换去掉变量的const属性的理由之一。


显然,多线程环境下,如果x、y、z可能被其它线程修改,所以每次用到都要重新读取;或者,在某些机器上,外设端口和内存统一编址,那么这个地址的数据显然会随时间改变,每次都必须重新读取。这时就必须用volatile来修饰它们了。



//=============
比如全局int a;
thread1修改a为2,但这次只在寄存器中修改,之后发生线程上下文切换,到thre2,thre2读取a的数据就出问题了?
//=============

是的。编译器的确会这样优化。所以才必须有volatile关键字来明确阻止这种错误的优化。这也是编写多线程程序的难点之一。

论坛徽章:
0
5 [报告]
发表于 2011-08-26 15:38 |只看该作者
回复 4# 狗蛋


回头找时间测试下,如果真会那样优化,窃以为不大好。。。

论坛徽章:
0
6 [报告]
发表于 2011-08-26 15:46 |只看该作者
多谢各位兄台~

论坛徽章:
12
巳蛇
日期:2013-09-16 15:32:242015年辞旧岁徽章
日期:2015-03-03 16:54:152015年亚洲杯之约旦
日期:2015-02-11 14:38:37双鱼座
日期:2015-01-05 11:05:47戌狗
日期:2014-12-08 09:41:18戌狗
日期:2014-08-15 09:29:29双子座
日期:2014-08-05 09:17:17卯兔
日期:2014-06-08 15:32:18巳蛇
日期:2014-01-27 08:47:08白羊座
日期:2013-11-28 21:04:15巨蟹座
日期:2013-11-13 21:58:012015年亚洲杯之科威特
日期:2015-04-17 16:51:51
7 [报告]
发表于 2011-08-26 15:50 |只看该作者
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP