我对特殊POPL问题Java内存模型论文中的图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
if x or y == 1
而x or y could be == 1
仅if r1 and r2 == 1
。但是1
的分配我只能在r3 = r2 | 1;
中找到。所以我认为没有办法让1
转到r1
,r2
,{{1} }或x
。
那么,这个例子是错的还是我弄错了?
答案 0 :(得分:1)
Initially, x == y == 0
Thread 1 -> r1 = x; y = r1;
Thread 2 -> r2 = y; r3 = r2 | 1; x = r3;
您可以在Jeremy Manson's PhD dissertation的图1.3中看到正确的示例。