我对 SPECIAL POPL ISSUE The Java Memory Model 论文中的图 3 感到困惑。
示例(第 5 页,图 3):
Initially, x == y == 0
Thread 1 -> r1 = x; y = r1;
Thread 2 -> r2 = y; r3 = r2 | 1; x = r2;
r1 == r2 == r3 == 1 is legal behavior.
解释 1(第 5 页,1.2 偶然循环):因果循环的另一个示例——这一次,描述了可接受的行为——可以在图 3 中看到。为了看到结果r1 == r2 == r3 == 1
,其中一个线程必须执行其写入在它执行读取之前。但是每次写入似乎都依赖于它上面的读取。虽然这个值似乎也是凭空而来的,但它不是而且可能是标准编译器转换的结果,如第 2.2.2 节所述。
解释 2(第 10 页,2.2.2 依赖破坏分析和转换):图 3 显示了类似但更令人惊讶的行为。在这种情况下,编译器必须执行更深入的分析,以确定 x 和 y 的值保证为 0 或 1。一种可能的此类分析是确定表示整数所需的位宽的分析程序中的值 [Stephenson et al. 2000]。
在这个例子中 r1 和 r2 可以是== 1
onlyif x or y == 1
和x or y could be == 1
only if r1 and r2 == 1
。但是 I的分配1
只能在r3 = r2 | 1;
所以我认为没有办法1
到达r1
,r2
或.x
y
那么,这个例子是错误的还是我错了?