重排序是指编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段
数据依赖
如果两个操作访问同一变量,且存在一个写操作,这两个操作就存在数据依赖
数据依赖的三种类型:
名称 | 代码示例 |
---|---|
写后读 | a=1;b=a; |
写后写 | a=1;a=2; |
读后写 | a=b;b=1; |
存在数据依赖的操作进行指令重排,程序的执行结果可能就会被改变. 编译器和处理器在重排序时,会遵守数据依赖性,编译器和处理器不会改变存在数据依赖关系的两个操作的执行顺序
这里所说的数据依赖性仅针对单个处理器中执行的指令序列和单个线程中执行的操作, 不同处理器之间和不同线程之间的数据依赖性不被编译器和处理器考虑
as-if-serial 语义
as-if-serial语义的意思是:不管怎么重排序(编译器和处理器为了提高并行度),(单线程)程序的执行结果不能被改变
在单线程程序中,对存在控制依赖的操作重排序,不会改变执行结果(这也是as-if-serial 语义允许对存在控制依赖的操作做重排序的原因);但在多线程程序中,对存在控制依赖的操 作重排序,可能会改变程序的执行结果
文章链接 https://fangzongzhou.github.io/2020/10/15/计算机/技术栈/Java/并发编程/指令重排/