如何禁止CPU指令重排
CPU的内存屏障(硬件层级)
Intel的CPU内存屏障逻辑:
sfence:save| 在sfence指令前的写操作当必须在sfence指令后的写操作前完成
两条指令,如果不想让它重排,在两条指令中间加一道屏障。即 屏障两侧的写指令不能重排
lfence:load| 在lfence指令前的写操作当必须在lfence指令后的写操作前完成
mfence:mix| 在mfence指令前的写操作当必须在mfence指令后的写操作前完成
除了内存屏障,也可以使用原子指令,如x86上的"lock..." lock后面的指令不允许重排序
JVM级别的规范(软件层级)
LoadLoad屏障:
对于这样的语句Load1;LoadLoad;Load2,在Load2及后续读取操作要读取的数据被访问前,保证Load1要读取的数据被读取完毕
SroreStore屏障:
对于这样的语句Store1;SroreStore;Store2,在Store2及后续写入操作要读取的数据被访问前,保证Store1的写入操作对其他处理器可见
LoadStore屏障:
对于这样的语句Load1; LoadStore; Store2,在Store2及后续写入操作被刷出前,保证Load1要读取的数据被读取完毕。
StoreLoad屏障:
对于这样的语句Store1; StoreLoad; Load2,在Load2及后续所有读取操作执行前,保证Store1的写入对所有处理器可见。
volatile的实现细节
1.字节码层面 ,编译完成在Class文件上加了ACC_VOLATILE
2.JVM层面读到ACC_VOLATILE时,会内存区的读写 都加屏障
StoreStoreBarrier
volatile 写操作
StoreLoadBarrier
LoadLoadBarrier
volatile 读操作
LoadStoreBarrier
volatile保证可见性的原理是添加内存屏障,而这些内存屏障在保障了线程之间的可见性的同时,也禁止了指令重排序。
3.操作系统OS实现
OS和硬件层面 https://blog.csdn.net/qq_26222859/article/details/52235930
hsdis - HotSpot Dis Assembler
windows lock 指令实现 | MESI实现