重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
如果两个操作同时访问同一个变量,且存在写操作,那么这两个操作就存在数据依赖性。
数据依赖性分为三种:
上面三种情况如果操作重排序,就有可能会改变执行结果。所以编译器和处理器在重排序的时候不会对存在数据依赖性的操作进行重排序。
注:数据依赖性仅针对单个处理器中执行的指令序列和单个线程中执行的操作。
解释:不管怎么重排序,(单线程)程序的执行结果不能改变。编译器处理器runtime都必须遵守as-if-serial语义。
3、程序顺序规则遵守happens-before规则。
JMM仅仅要求前一个操作(执行的结果)对后一个操作可见,且前一个操作按顺序排在第二个操作之前。
重排序会影响多线程的程序执行结果。
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中。
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧