• "Loads are not reorderd with other loads" is a FACT!! 续:不要指望 volatile


    上一篇随笔中提到了volatile,实际上由于上一篇中提到的问题,volatile已经越来越远离其应有的含义了。在说这个问题之前,我们又要提.NET的内存模型问题(以下简称MM),我不指望在这里长篇大论的说其内存模型是如何的。简单的说就是以下的几句话:

    第一、load与store之间的数据依赖关系不会被改变

    第二、所有的store操作都有release语义,所有的volatile的load都有acquire语义,

    第三、所有的load与store都不能跨越memory barrier(full fence,全内存栅栏)

    第四、load和store仅仅在紧邻的对于相同位置的load和store存在时才可能被移除。

    所谓acquire与release是怎么一回事,这个~acquire可以理解为,没有其他的操作(对内存的)可以将自己执行的顺序调整到它之前;相反的,release可以理解为,没有其他的操作可以将自己的执行调整到它之后。但是请注意!acquire和release已经是半个内存栅障了!他应该对CPU的可见性产生影响。好,我们先不提这个,假设MS目前的x86, x64上的.NET的MM是完美实现的。看看MSDN对volatile的解释是什么:

    第一句:

    The volatile keyword indicates that a field might be modified by multiple threads that are executing at the same time.

    这句实际上没有说任何的实际内容。

    第二句:

    Fields that are declared volatile are not subject to compiler optimizations that assume access by a single thread.

    这句指出了volatile的一个作用--防止编译器优化你的代码,虽然提到了编译器对于volatile不再认为是单线程访问的,但是仅仅是assume,这并不能解决任何问题。

    第三句:

    This ensures that the most up-to-date value is present in the field at all times.

    这是什么?这完全说明了我们上面所说的volatile的作用:volatile的load具有release语义!

    第四句:

    The volatile modifier is usually used for a field that is accessed by multiple threads without using the lock statement to serialize access.

    实际上他想说,如果你向volatile中执行了store,那么你在load中(即使在另一个线程)也会获得most up to date的值。这样我们就不必使用lock再引入同步或者memory fence了。

    好了,按照上面的解释,如果.NET的MM是完美实现了的,OK,全部说得过去!但是请看上一篇随笔,不是的!volatile根本不能保证load是acquire的!也就是,Microsoft的.NET Framework在x86与Intel 64的平台下的实现是有漏洞的(这跟Intel一点没有关系,不要误会,是.NET的MM的问题)!因此,不要指望MSDN的解释了。在你书写Multi-thread Application的时候,还是多留一个心眼吧。

    如果要修补这个漏洞,那么volatile的load需要半个memory fence,但是请看看x86,x64的文档,你就知道,这里不得不要一个full fence。也就是,volatile的load是完全不会被reorder的,这合适么?我不知道,我不知道真正的Java MM的官方解释在哪里,但是目前至少有文档表明,Java的volatile是一个full fence。

    最后,我想说明一点。大部分战友们,大部分时间内,根本不用为这个操心劳神。Please don't be panic:-)

  • 相关阅读:
    Access中出现改变字段“自己主动编号”类型,不能再改回来!(已解决)
    移动闭塞
    信号系统基本设备介绍——应答器
    行车闭塞
    计轴
    联锁
    SqlServer 查看缓存 并合理设置最大内存
    SQL Server中bcp命令的用法以及数据批量导入导出
    5 个免费的受欢迎的 SQLite 管理工具
    Qt之操作数据库(SQLite)
  • 原文地址:https://www.cnblogs.com/lxconan/p/1246776.html
Copyright © 2020-2023  润新知