JMMの因果関係は、その中で最も紛らわしい部分のようです。JMMの因果関係、および並行プログラムで許可される動作に関していくつか質問があります。
私が理解しているように、現在のJMMは常に因果関係のループを禁止しています。(私は正しいですか?)
ここで、JSR-133ドキュメント、24ページ、図16に従って、次の例があります。
最初はx = y = 0
スレッド1:
r3 = x;
if (r3 == 0)
x = 42;
r1 = x;
y = r1;
スレッド2:
r2 = y;
x = r2;
直感的には、r1 = r2 = r3 = 42
不可能のようです。ただし、可能な限り言及されているだけでなく、JMMでは「許可」されています。
可能性として、私が理解できない文書からの説明は次のとおりです。
コンパイラーは、これまでに割り当てられた唯一の値が0と42であると判断できます。それから、コンパイラーは、実行した時点で、42の書き込みを実行したか、 読み取りと表示を行っただけ
x
であると推測できます。値42。いずれの場合も、の読み取りで値42を確認することは合法です。その後、 ;に変更される可能性があります。これにより、以前に変換して実行できるようになり、問題の動作が発生します。この場合、書き込み先が最初にコミットされます。r1 = x
x
x
x
r1 = x
r1 = 42
y = r1
y = 42
y
私の質問は、それは本当にどのようなコンパイラの最適化ですか?(私はコンパイラーを認識していません。)42は条件付きでのみ記述されるため、if
ステートメントが満たされた場合、コンパイラーはどのようにしてx
?
第二に、コンパイラーがこの投機的最適化を行い、コミットy = 42
して最終的に作成r3 = 42
したとしても、因果関係の区別が残っていないため、因果関係ループの違反ではありませんか?
実際、同じ文書(15ページ、図7)には、同様の因果ループが許容できないと言及されている例が1つあります。
では、なぜこの実行順序がJMMで合法なのですか?