读书笔记-JMM-重排序


重排序是指编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段。

1、数据依赖性

如果两个操作同时访问同一个变量,且存在写操作,那么这两个操作就存在数据依赖性。
数据依赖性分为三种:

  1. 写后读。
  2. 写后写。
  3. 读后写。

上面三种情况如果操作重排序,就有可能会改变执行结果。所以编译器和处理器在重排序的时候不会对存在数据依赖性的操作进行重排序
注:数据依赖性仅针对单个处理器中执行的指令序列和单个线程中执行的操作。

2、as-if-serial语义

解释:不管怎么重排序,(单线程)程序的执行结果不能改变。编译器处理器runtime都必须遵守as-if-serial语义。

3、程序顺序规则

遵守happens-before规则。
JMM仅仅要求前一个操作(执行的结果)对后一个操作可见,且前一个操作按顺序排在第二个操作之前。

4、重排序对多线程的影响

重排序会影响多线程的程序执行结果。

class ReorderExample {
	int a = 0;
	boolean flag = false;
	public void writer() {
		a = 1; // 1
		flag = true; // 2
	}
	Public void reader() {
		if (flag) { // 3
			int i = a * a; // 4
			……
		}
	}
}

当有两个线程A和B顺序操作writer()和reader()方法时,执行操作4时不一定能看到操作1对共享变量a的写入。因为操作1和操作2不存在数据依赖性,操作3和操作4也不存在数据依赖性,可以对他们重排序。
操作3和操作4存在控制依赖性,会影响指令序列的并行度。为此,编译器和处理器会采用猜测(Speculation)执行来克服控制相关性对并行度的影响
以处理器的猜测执行为例,执行线程B的处理器可以提前读取并计算a*a,然后把计算结果临时保存到一个名为重排序缓冲(ReorderBuffer,ROB)的硬件缓存中。当操作3的条件判断为真时,就把该计算结果写入变量i中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值