volatile、内存屏障、内存乱序小结

C 语言中的volatile关键字作用?

易变性:volatile告诉编译器,某个变量是易变的,当编译器遇到这个变量的时候,只能从变量的内存地址中读取这个变量,不可以从缓存、寄存器、或者其它任何地方读取。
顺序性:两个包含volatile变量的指令,编译后不可以乱序。注意是编译后不乱序,但是在执行的过程中还是可能会乱序的,这点需要由其它机制来保证,例如memory- barriers。

Java中的volatile关键字作用?

Java的volatile关键字在语义上有所增强,主要体现在:

Java Volatile变量的操作,附带了Acquire与Release语义。所谓的Acquire与Release语义,可参考文章:Acquire and Release Semantics。(这一点,后续有必要的话,可以写一篇文章专门讨论)。Java Volatile所支持的Acquire、Release语义,如下:

  • 对于Java Volatile变量的写操作,带有Release语义,所有Volatile变量写操作之前的针对其他任何变量的读写操作,都不会被编译器、CPU优化后,乱序到Volatile变量的写操作之后执行。
  • 对于Java Volatile变量的读操作,带有Acquire语义,所有Volatile变量读操作之后的针对其他任何变量的读写操作,都不会被编译器、CPU优化后,乱序到volatile变量的读操作之前进行。
    通过Java Volatile的Acquire、Release语义,对比C/C++ Volatile,可以看出,Java Volatile对于编译器、CPU的乱序优化,限制的更加严格了。Java Volatile变量与非Volatile变量的一些乱序操作,也同样被禁止。
什么是happens-before?

令A和B表示两组操作,如果A happens-before B,那么由A操作引起的内存变化,在B开始执行之前,都应该是可见的。
A happens-before B,不代表A在B之前执行!

int A = 0;
int B = 0;

void foo()
{
    A = B + 1;              // (1)
    B = 1;                  // (2)
}

上述的代码,满足A happens-before B,但是语句(2)可能在(1)之前执行。

所以如果有另外一个线程,尝试去读取B的值,然后再读A的值,那么可能就会有问题:

if (B == 1)
{
    assert(A == 2); // 错误!A可能还是0
}
如何确保happen-before?

锁(互斥锁、读写锁等)、内存屏障

指令乱序

指令乱序是指程序在执行代码的时候,并不按代码编写的实际顺序执行。这种情况可能发生在两个阶段,一个是编译阶段,一个是运行阶段。
关于编译阶段的乱序,参考资料中何登成的博客中给出了示例,这里就不赘述。C的volatile关键字,只能保证编译阶段不乱序,但是不能保证运行时不乱序。

什么是内存屏障(memory barriers)?

内存屏障是一个指令,这个指令可以保证屏障前后的指令遵守一定的顺序,并且保证一定的可见性,具体的,在典型的Inter X86架构上,有以下几种内存屏障指令:

  • sfence:保证此fence指令之前的所有写操作,先于(happens-before)屏障之后的所有写操作。
  • lfence:保证此fence指令之前的所有读操作,先于(happens-before)屏障之后的所有读操作。
  • mfence:相当于sfence + lfence。

关于常见的内存屏障,见:MemoryBarriers

另附自己使用内存屏障实现的一个无锁类似ring buffer的实现:https://github.com/jiafujiang/SampleC/tree/master/src/ring_buffer_sample

ping-pong时间大概在几百ns这个级别,不同的机器会有不同的表现。

另外附上朋友写的一个Java版的实现:https://github.com/nottryhard/something/blob/master/src/RingBuffer.java

参考资料:

何登成的技术博客
the-happens-before-relation

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容

  • 并发系列的文章都是根据阅读《Java 并发编程的艺术》这本书总结而来,想更深入学习的同学可以自行购买此书进行学习。...
    小之丶阅读 1,035评论 1 7
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,170评论 11 349
  • 最近看了优酷中一席的朱赢椿《慢慢慢下来》。他跪着说话与站着说话。慢下来看身边(蜗牛与湖)。没有时间的一天。 开始听...
    六day阅读 375评论 1 1
  • 高晓松2014年演唱会北京站已过去两月有余,现在还留有的印象应该是比较深刻且客观,絮絮道来权当给自己留个念想儿...
    关宁铁骑阅读 1,903评论 1 2
  • 1、统计局:2016年12月份全国居民消费价格指数同比上涨2.1%,环比上涨0.2%;工业生产者出厂价格指数PPI...
    RL_A阅读 131评论 0 0