为什么会有指令重排序
现代处理器会设计为一个时钟周期完成一条执行时间最长的CPU指令,每条指令可以划分为:
取指令->指令译码->执行指令->内存访问->数据写回 五个阶段
串行执行
多级指令流水线
这时CPU可以在一个时钟周期内,同时运行五条指令的不同阶段,提高了指令的吞吐率
重排序意义
处理器为提高运算速度而做出违背代码原有顺序的优化。
volatile原理
volatile的底层实现原理是内存屏障:
- 对volatile变量的写指令后会加入写屏障
- 对volatile变量的读指令前会加入读屏障
如何保证可见性
写屏障保证在该屏障之前的对共享变量的改动,都同步到主存当中
应用后保证了num=2同步到了主存中
读屏障保证了在该屏障之后,对共享变量的读取,加载的是主存中最新数据
如何保证有序性
写屏障会确保指令重排序时,不会将写屏障之前的代码排在写屏障之后
读屏障会确保指令重排序时,不会将读屏障之后的代码排序在读屏障之前
不能解决指令交错
- 写屏障仅仅保证之后的读能够读到最新结果,但不能保证第二个线程在写入之前就已经读到了他前面去
- 而有序性的保证也只是保证了本线程内相关代码不被重排序
重排序规则
- 当第二个操作是volatile写时,为了保证可见性(即在volatile写的后面加上写屏障,保证写屏障前面的数据都保存到主存中),不能将前面的操作重排序到volatile写之后去
- 当第一个操作是volatile读时,会在volatile读的前面加上读屏障,为了保证可见性,即在读屏障的对共享变量的读取,都读到的时最新数据,不能将他们重排序到volatile前面
- 当第一个操作时volatile写时,第二个操作时volatile读时,为了保证能读到最新数据,则不能重排序