從java程式碼到指令序列的重排序
阿新 • • 發佈:2022-05-29
在執行程式時,為了提高效能,編譯器和處理器會對指令重排序。重排序分為三種:
- 編譯器優化的重排序。在不改變程式語義的前提下,可以改變執行順序。如下:
a = 1;
b = 2;
// 重排序後 ====>
b = 2;
a = 1;
- 指令級並行的重排序。如果不存在資料依賴性,處理器可以改變語句對應的機器指令的執行順序。比如singleton = new Singleton()這一句java程式碼會被JVM生成如下三條指令,但是因為指令2和3之間沒有資料依賴性,所以可能被處理器重排而先執行指令3。
- 分配記憶體物件;
- 呼叫構造器初始化;
- 構建物件引用指向記憶體物件。
- 記憶體系統的重排序。由於處理器使用了快取和讀寫緩衝區,這使得讀和寫看上去可能是在亂序執行。翻譯一下,就是處理器修改了變數a的值,但是出於效能考慮並沒有立即回寫到記憶體,然後處理器又去記憶體裡面讀取了變數b,最後處理器執行完後才將變數a寫回到記憶體,所以真正執行指令的時候寫變數a的指令是在讀變數b指令之後,但事實上寫a是先發生的。