Przyczynowość w JMM wydaje się być najbardziej zagmatwaną częścią tego. Mam kilka pytań dotyczących związku przyczynowego JMM i dozwolonych zachowań w programach współbieżnych.Dlaczego to zachowanie jest dozwolone w modelu pamięci Java?
Jak rozumiem, obecne JMM zawsze zabrania pętli przyczynowości. (Mam rację?)
Teraz, jak na dokumencie JSR-133, strona 24, Rys.16 mamy przykład, w którym:
Początkowo x = y = 0
gwintu 1:
r3 = x;
if (r3 == 0)
x = 42;
r1 = x;
y = r1;
gwintu 2:
r2 = y;
x = r2;
Intuicyjnie, r1 = r2 = r3 = 42
wydaje się niemożliwe. Jednak jest to nie tylko wymieniane jako możliwe, ale także "dozwolone" w JMM.
możliwość, wyjaśnienie od dokumentu, który nie rozumiem jest:
Kompilator może określić, że tylko wartości zawsze są przypisane do
x
0 i 42. Z tego, kompilator mógł Wydedukować, że w punkcie , gdzie wykonaliśmyr1 = x
, albo właśnie wykonaliśmy zapis 42 dox
, albo właśnie przeczytaliśmyx
i zobaczyliśmy wartość 42. W każdym przypadku to byłoby legalne dla odczytu zx
, aby zobaczyć wartość 42. Może następnie zmienićr1 = x
nar1 = 42
; pozwoliłoby to na przekształceniey = r1
nay = 42
i wykonano wcześniej, powodując zachowanie w postaci . W takim przypadku zapis doy
jest najpierw zatwierdzony jako .
Moje pytanie brzmi, jaki rodzaj optymalizacji kompilacji jest naprawdę? (Jestem ignorantem kompilatora.) Ponieważ 42 jest napisane tylko warunkowo, gdy stwierdzenie if
jest spełnione, w jaki sposób kompilator może zdecydować się na napisanie x
?
Po drugie, nawet jeśli robi to kompilator optymalizacji spekulacyjnego oraz zobowiązuje y = 42
i wreszcie sprawia r3 = 42
, nie jest to naruszenie pętli przyczynowości, ponieważ nie ma przyczyny i skutku rozróżnienie lewo teraz?
W rzeczywistości istnieje jeden przykład w tym samym dokumencie (strona 15, rysunek 7), w którym podobna pętla przyczynowa została wymieniona jako niedopuszczalna.
Jak to możliwe, że ten nakaz wykonania jest legalny w JMM?
@Alexei To wyjaśnia niektóre z nich. Ale czy kompilator nie powinien uczynić go 'r3 = 0' zamiast' r3 = 42'? Lub po prostu pokazują "możliwość"! – gaganbm
Kompilator nie tworzy 'r3 = 42', po prostu pozostawia' r3 = x' w stanie nienaruszonym. Optymalizacja kompilatora nie zawsze jest wykonywana na maksymalnej głębokości. Jeśli istnieje minimalna możliwość, że optymalizacja może naruszyć poprawność, jest ona porzucana. W podanym kodzie nie ma takich okoliczności, ale mogą się pojawić, gdy obecny jest inny kod. Poza tym, kompilator może zdecydować, że 'r3 = 0' ma tę samą cenę co' r3 = x'. –