• happens-before规则和指令重排


                                                                                                                       《JAVA并发编程实战》阅读笔记1
    一、 指令重排

    指令重排序

    Java 语言规范规定了JVM线程内部维持顺序化语义,也就是说只要程序的最终结果等同于它在严格的顺序化环境下的结果,那么指令的执行顺序就可能 与代码的顺序不一致。这个过程通过叫做指令的重排序。指令重排序存在的意义在于:JVM能够根据处理器的特性(CPU的多级缓存系统、多核处理器等)适当 的重新排序机器指令,使机器指令更符合CPU的执行特点,最大限度的发挥机器的性能。

    重排序的背景

    我们知道现代CPU的主频越来越高,与cache的交互次数也越来越多。当CPU的计算速度远远超过访问cache时,会产生cache wait,过多的cache  wait就会造成性能瓶颈。
    针对这种情况,多数架构(包括X86)采用了一种将cache分片的解决方案,即将一块cache划分成互不关联地多个 slots (逻辑存储单元,又名 Memory Bank 或 Cache Bank),CPU可以自行选择在多个 idle bank 中进行存取。这种 SMP 的设计,显著提高了CPU的并行处理能力,也回避了cache访问瓶颈。

    Memory Bank的划分
    一般 Memory bank 是按cache address来划分的。比如 偶数adress 0×12345000 分到 bank 0, 奇数address 0×12345100 分到 bank1。

    重排序的种类
    编译期重排。编译源代码时,编译器依据对上下文的分析,对指令进行重排序,以之更适合于CPU的并行执行。

    运行期重排,CPU在执行过程中,动态分析依赖部件的效能,对指令做重排序优化。

    二、 happens-before规则

    Java存储模型有一个happens-before原则,就是如果动作B要看到动作A的执行结果(无论A/B是否在同一个线程里面执行),那么A/B就需要满足happens-before关系。

    (1)同一个线程中的每个Action都happens-before于出现在其后的任何一个Action。

    (2)对一个监视器的解锁happens-before于每一个后续对同一个监视器的加锁。

    (3)对volatile字段的写入操作happens-before于每一个后续的同一个字段的读操作。

    (4)Thread.start()的调用会happens-before于启动线程里面的动作。

    (5)Thread中的所有动作都happens-before于其他线程检查到此线程结束或者Thread.join()中返回或者Thread.isAlive()==false。

    (6)一个线程A调用另一个另一个线程B的interrupt()都happens-before于线程A发现B被A中断(B抛出异常或者A检测到B的isInterrupted()或者interrupted())。

    (7)一个对象构造函数的结束happens-before与该对象的finalizer的开始

    (8)如果A动作happens-before于B动作,而B动作happens-before与C动作,那么A动作happens-before于C动作。

    三、 理解

         开始接触happens-before规则和指令重排序的时候,着实乱了以阵子,尤其是happens-before规则的第一条,明明说了同一个线程中每个动作都happens-before其后一个动作,
    而指令重排序又会对没有依赖的两个操作进行重排序,这不是相互矛盾的么?
         经过网上翻阅了一些资料以后,我的理解是,happens-before规则是用来判断一个动作对另一个动作是否可见的法则,他只是用来判断可见性的,而不是决定执行顺序的,就是说动作A和动作B 的执行顺序是可以通过指令重排发生变化的,而如果你要保证A和B的可见性关系,就必须采用其他控制手段来保证AB的执行顺序不被打乱,这样就能用happens-before规则来判断AB两个动作的可见性。 
     
     
    参考信息:
    http://www.infoq.com/cn/articles/java-memory-model-2?utm_source=infoq&utm_medium=related_content_link&utm_campaign=relatedContent_articles_clk
    http://www.blogjava.net/xylz/archive/2010/07/03/325168.html
  • 相关阅读:
    Java应用开发中的SQL注入攻击
    TOSCA自动化测试工具ppt
    SQL Server怎么备份数据库
    翻翻git之---一个丰富的通知工具类 NotifyUtil
    ZOJ
    高速掌握Lua 5.3 —— Lua与C之间的交互概览
    poj1649 Rescue(BFS+优先队列)
    面向对象在JavaScript中的接口实现
    dedecms织梦后台password忘记了怎么办?dedecms织梦后台password忘记怎样找回password?
    [ACM] POJ 3233 Matrix Power Series (求矩阵A+A^2+A^3...+A^k,二分求和或者矩阵转化)
  • 原文地址:https://www.cnblogs.com/vipper/p/3307991.html
Copyright © 2020-2023  润新知