JMMの因果関係は、最も混乱しているようです。私はJMM因果関係についていくつかの質問をしており、並行プログラムでの行動を許可しています。Javaメモリモデルでこの動作が許可されるのはなぜですか?
私が理解しているように、現在の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で「許可」されています。可能性を
、私は理解できない文書からの説明は次のとおりです。
コンパイラこれまで
x
に割り当てられた値のみがコンパイラができた、それから、 0および42であることを決定することができます我々がx
の書き込みを実行したか、またはx
を読んだだけで42の値を見たかのいずれかで、 を実行したと推測されます。どちらの場合でも、読み取りには合法ですの値を参照してください。その後、r1 = x
をr1 = 42
に変更することができます。これにより、y = r1
はy = 42
に変換され、先に実行され、結果として の問題が発生します。この場合、y
への書き込みは、最初に にコミットされます。
私の質問は、どのようなコンパイラの最適化は本当ですか? (私はコンパイラには無知です。)42は条件付きでしか書かれていないので、if
文が満たされたときに、コンパイラはx
の書き込みにどうすればいいですか?今残された原因と結果の区別がないので
は第二に、コンパイラは、この投機的な最適化を行い、最終的にr3 = 42
を行い、その後y = 42
と を犯したとしても、それは、因果関係ループの違反ではないのですか?
実際、同じ文書(15ページ、図7)には、同様の原因ループが許容できないと言われる例があります。
この実行命令はJMMではどのように合法ですか?
@アレクセイその一部を説明します。しかし、コンパイラは 'r3 = 42'の代わりに' r3 = 0'を作るべきではありませんか?あるいは、彼らは単に「可能性」を示しているだけです! – gaganbm
コンパイラは 'r3 = 42'を作成しません。' r3 = x'をそのまま残します。コンパイラの最適化は必ずしも最大深度まで実行されるわけではありません。最適化が正当性に違反する可能性が最小限であれば、それは放棄されます。与えられたコードでは、そのような状況はありませんが、他のコードがあれば現れることがあります。また、コンパイラは 'r3 = 0'が' r3 = x'と同じ価格であると判断できます。 –