重排序

什么是重排序?

计算机在执行程序时,为了提高执行效率编译器处理器会对指令进行重排

为什么重排序可提高性能?

现代CPU使用流水线技术,多个指令可以同时执行。

例如下面的代码

a = b + c;
d = e - f;

先加载 b,c 但在执行 b + c 的时候,需要等待 b,c 加载完成,也就也是增加了停顿,后面的指令在等待 b + c 完成。

为了减少停顿,我们可以先加载 e,f 然后再加载 b + c。这对程序执行没有影响,却提高了效率。

指令重排带了了乱序的问题,但大大提高了CPU的执行效率

指令重排一般有三种:

  • 编译器优化重排

不改单线程程序语义的情况下,重新安排指令的执行顺序。

  • CPU指令并行重排

如果指令间不存在数据依赖(后面的语句依赖前面的结果),CPU可以改变机器指令的执行顺序。

  • 内存系统重排

因为CPU使用缓存,是的 load 和 store 操作看上去在乱序执行,因为三级缓存的存在,导致内存和缓存的同步存在时间差。

指令重排可以保证串行语义一致,但没有义务保证多线程语义一致

顺序一致性

顺序一致性:

  • 一个线程中所有操作必须按照程序的顺序来执行
  • 不管程序是否同步,所有线程只能看到一个单一的执行顺序。即每个操作是原子的,并立刻对所有线程可见

JMM 并没有提供这样保证

JMM 顺序一致性

同步程序

JMM 中,临界区内的代码可以发生重排序。

JMM 会在进入和退出临界区做特殊处理,使得在临界区内程序获得与顺序一致性模型相同的内存视图

JMM的具体实现方针是:在不改变(正确同步的)程序执行结果的前提下,尽量为编译期和处理器的优化打开方便之门

未同步的程序

JMM 提供最小安全性

线程读到的值

  • 要么是默认值
  • 要么是之前某个线程写入的值

JMM 不保证 未同步程序 执行结果与该程序顺序一致性执行结果一致

未同步程序在 JMM 和 顺序一致性 执行差异:

顺序一致性JMM
单线程按照程序顺序执行不保证按照程序顺序执行,但保证重排序不影响结果。
操作执行顺序保证所有线程看到一致的顺序不保证所有线程看到一致的执行顺序(JMM 不保证所有操作立即可见)
内存内存读写原子性不保证 64 位的 long 和 double 类型写操作原子性。

happens-before

什么是 haapens-before

一方面,程序员需要 JMM 提供一个强的内存模型来编写代码;另一方面,编译器和处理器希望 JMM 的束缚越少越好,这样它们可以做尽可能多的优化,希望有一个弱的内存模型。

JMM 考虑了这两种需求,找到了平衡点,对编译器和处理器来说:只要不改变程序的执行结果(单线程程序和正确同步了的多线程程序),编译器和处理器怎么优化都行。

对于程序员,JMM 提供了 happens-before规则(JSR-133规范),简单易懂,并提供了足够强的内存可见性保证。

JMM 使用 happens-before 的概念来定制两个操作间的执行顺序。这两个操作可以在一个线程以内,也可以是不同的线程之间。因此,JMM可以通过happens-before关系向程序员提供跨线程的内存可见性保证。

happens-before 定义:

  • 如果一个操作 happens-before 另一个操作,第一个操作执行结果对第二个操作可见,且第一个操作操作的执行顺序排在第二个操作之前。
  • 两个操作存在 happens-before 关系,并不意味着 Java 平台的具体实现按照 happens-before 指定顺序执行。在保证结果一致的前提下,JMM 也运行重排序。

简而言之,如果 A happens-before B, 那么 A内存上所做的操作对于 B 都是可见的,不管它们在不在一个线程中。

天然的 happens-before 关系

  • 程序顺序:一个线程中每一个操作,happens-before 该线程中任意后续操作
  • 监视器锁: 一个锁的解锁,happens-before 随后对改锁的加锁
  • volatile:对一个 volatile 域的写,happens-before 于任意后续对这个 volatile 域的读
  • 传递性: A happens-before B, B happens-before C, 那么 A happens-before C
  • start: 线程 A 执行 threadB.start() , threadB.start() 操作 happens-before 于 B的任意操作
  • join: 线程 A 执行 threadB.join(), 线程B的任意操作 happens-before 于线程A从 threadB.join()的返回。
Last Updated:
Contributors: himcs