我書面方式這篇文章中的連接上下文的JIT產生的x86輸出到Deep understanding of volatile in Java分析中的揮發性
public class Main {
private int x;
private volatile int g;
public void actor1(){
x = 1;
g = 1;
}
public void actor2(){
put_on_screen_without_sync(g);
put_on_screen_without_sync(x);
}
}
現在,我分析了上面這段代碼生成了什麼JIT。從我們在我以前的帖子討論中,我們知道,輸出1, 0
是不可能的,因爲:
寫揮發性v
使每一個動作a
前述v
導致該a
將是可見的(將被刷新到內存)v
之前將可見。
.................(I removed not important body of method).....
0x00007f42307d9d5e: c7460c01000000 (1) mov dword ptr [rsi+0ch],1h
;*putfield x
; - package.Main::[email protected] (line 14)
0x00007f42307d9d65: bf01000000 (2) mov edi,1h
0x00007f42307d9d6a: 897e10 (3) mov dword ptr [rsi+10h],edi
0x00007f42307d9d6d: f083042400 (4) lock add dword ptr [rsp],0h
;*putfield g
; - package.Main::[email protected] (line 15)
0x00007f42307d9d72: 4883c430 add rsp,30h
0x00007f42307d9d76: 5d pop rbp
0x00007f42307d9d77: 850583535116 test dword ptr [7f4246cef100h],eax
; {poll_return}
0x00007f42307d9d7d: c3 ret
難道我理解正確的話,它的作品,因爲86不能讓StoreStore
重新排序?如果可能的話,將需要額外的內存屏障,是嗎?
EDITED優秀@尤金的答案AFTER:
int tmp = i; // volatile load // [LoadStore] // [LoadLoad]
在這裏,我看你是什麼均值很明顯:every action below (after)
性讀(int tmp = i
)不會重新排序。
// [StoreLoad] -- this one int tmp = i; // volatile load // [LoadStore] // [LoadLoad]
在這裏,你放多了一個障礙。它確保我們不會對int tmp = i
重新排序。但是,爲什麼它很重要?爲什麼我有疑問?從我所知道的volatile load
保證:
每個行動後揮發性負載將不會被重新排序之前,易失性負載是可見的。
我看你寫的:
需要有一個順序一致性
但是,我不明白爲什麼需要順序一致性。
什麼'a'?什麼'V'?你的意思是'x'和'g'? – Andreas
現在,'a'是'v'上的任何動作 - 例如它是一個動作:'x = 1'。 'v'是一個商店:'g = 1' – Gilgamesz
JMM不是爲x86或任何其他特定的體系結構而製作的,並且在加載或存儲方面沒有任何理由。 JVM有責任按照每個體系結構上的指令來實現JMM。 – assylias