JMM——重排序与内存屏障

重排序

在执行程序时为了提高性能,编译器和处理器常常会对指令做重排序

重排序有三种类型:

1.编译器优化的重排序

编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序

2.指令级并行的重排序

现代处理器采用了指令级并行技术来将多条指令重叠执行。

如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序

3.内存系统的重排序

由于处理器使用缓存和读/写缓冲区,这使得加载和存储操作看上去可能是在乱序执行



对于编译器,JMM的编译器重排序规则会禁止特性类型的编译器重排序

 

JMM属于语言级的内存模型,它确保在不同的编译器和不同的处理器平台之上,通过禁止特定类型的编译器重排序和处理器重排序,为程序员提供一致的内存可见性保证


处理器重排序与内存屏障指令

现代处理器使用写缓冲区来临时保存向内存写入的数据

写缓冲区可以保证指令流水线持续运行,它可以避免由于处理器停顿下来等待向内存写入数据而产生的延迟

同时,通过以批处理的方式刷新写缓冲期,以及合并写缓冲区中对同一内存地址的多次写,可以减少对内存总线的占用

 

每个处理器上的写缓冲区,仅仅对它所在的处理器可见,这个特性会对内存操作的执行顺序产生重要的影响:处理器对内存的读/写操作的执行顺序不一定与内存实际发生的读/写操作顺序一致


处理器A和处理器B可能同时把a和b写入各自的写缓冲区

再从内存中读取对方的共享变量a和b赋值给x和y

最后才把自己写缓冲区中保存的脏数据(a和b)刷新到内存中

把本来应该是A1->A3->A2的内存操作重排序为A1->A2->A3了

导致处理器和内存执行的操作不一致


内存屏障

对于处理器重排序,JMM的处理器重排序规则会要求java编译器在生成指令序列时插入特定类型的内存屏障(memory barriers, intel称之为memory fence)指令

通过内存屏障指令来禁止特定类型的处理器重排序



















没有更多推荐了,返回首页