1

我对 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 可以是== 1onlyif x or y == 1x or y could be == 1only if r1 and r2 == 1。但是 I的分配1只能在r3 = r2 | 1;所以我认为没有办法1到达r1,r2或.xy

那么,这个例子是错误的还是我错了?

4

1 回答 1

1

你是对的。这个例子是错误的。它应该是:

Initially, x == y == 0
Thread 1 -> r1 = x; y = r1;
Thread 2 -> r2 = y; r3 = r2 | 1; x = r3;

您可以在Jeremy Manson 博士论文的图 1.3 中看到正确的示例。

于 2013-10-06T16:59:49.753 回答