文章目录
1. 缓存一致性
为了保证内存可见性,Java 编译器在生成指令序列的适当位置会插入内存屏障指令来禁止特定类型的处理器重排序。JMM 把内存屏障指令分为4类
在计算机中,cpu和内存的交互最为频繁,相比内存,磁盘读写太慢,内存相当于高速的缓冲区。
但是随着cpu的发展,内存的读写速度也远远赶不上cpu。因此cpu厂商在每颗cpu上加上高速缓存,用于缓解这种情况
cpu上加入了高速缓存这样做解决了处理器和内存的矛盾(一快一慢),但是引来的新的问题 - 缓存一致性
在多核cpu中,每个处理器都有各自的高速缓存(L1,L2,L3),而主内存确只有一个
CPU要读取一个数据时,首先从一级缓存中查找,如果没有找到再从二级缓存中查找,如果还是没有就从三级缓存或内存中查找,每个cpu有且只有一套自己的缓存
2. 指令重排
指令重排是指编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段。
2.1. 重排的类型
指令重排的类型分3种:
- 编译器优化的重排
编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序 - 指令级并行的重排
现代处理器采用了指令级并行技术(Instruction-Level Parallelism,ILP)来将多条指令重叠执行。如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序 - 内存系统的重排
由于处理器使用缓存和读/写缓冲区,这使得加载和存储操作看上去可能是在乱序执行
1属于编译器重排序,2和3属于处理