CPU指令乱序学习笔记

CPU的乱序执行(JAVA中的指令重排序)

CPU在进行读等待的同时(由于CPU效率是内存的近一百倍)执行指令,是CPU乱序的根源,同时也是提高效率的手段。

CPU层面如何禁止重排序

内存屏障(对某部分内存做操作时前后添加的屏障前后操作不可以乱序执行)

intel提供三种原语或者锁总线来保证:

sfence:在sfence指令前的写操作当必须在sfence指令后的写操作前完成。

lfence:在lfence指令前的读操作当必须在Ifence指令后的读操作前完成。

mfence:在mfence指令前的读写操作当必须在mfence指令后的读写操作前完成。

lock汇编指令(不止intel,许多CPU都有):

原子指令,如x86上的”lock …”指令是一个FullBarrier,执行时会锁住内存子系统来确保执行顺序,甚至跨多个CPU。Software Locks通常使用了内存屏障或原子指令来实现变量可见性和保持程序顺序

虽然三种原语效率更高,许多其他CPU没有,因此HOTSPOT JVM在实现时便使用的lock指令。

JVM防止乱序8个hanppens-before原则4个内存屏障:

JSR(JavaSpecification Requests的缩写,意思是“Java 规范提案”)内存屏障:

LoadLoad屏障:
对于这样的语句Load1; LoadLoad; Load2,
在Loadz及后续读取操作要读取的数据被访问前,保证Load1要读取的数据被读取完毕。
StoreStore屏障:
对于这样的语句Store1; StoreStore; Store2,
在Store2及后续写入操作执行前,保证Store1的写入操作对其它处理器可见。
LoadStore屏障:
对于这样的语句Loadi; LoadStore; Store2,
在Store2及后续写入操作被执行前,保证Load1要读取的数据被读取完毕。
StoreLoad屏障:

​ 对于这样的语句Store1; StoreLoad; Load2,
​ 在Load2及后续所有读取操作执行前,保证Store1的写入对所有处理器可见。

volatile的实现细节(JVM层面):

防止写的指令重排序及保证可见性

StoreStoreBarrier

volatile 写操作

StoreLoadBarrier

防止读的指令重排序及保证可见性

LoadLoadBarrier

volatile读操作

LoadStoreBarrier

了解:

在这里插入图片描述

as-if-serial:不管硬件什么执行顺序,单线程执行的结果不变,看上去是顺序。

erial:不管硬件什么执行顺序,单线程执行的结果不变,看上去是顺序。

猜你喜欢

转载自blog.csdn.net/cao_luobin/article/details/113167896