happens-before规则和指令重排
?????????????????????????????????????????????????????????????????????????????????????????????????????????????????? 《JAVA并發編程實戰》閱讀筆記1
一、 指令重排
指令重排序
Java 語言規范規定了JVM線程內部維持順序化語義,也就是說只要程序的最終結果等同于它在嚴格的順序化環境下的結果,那么指令的執行順序就可能 與代碼的順序不一致。這個過程通過叫做指令的重排序。指令重排序存在的意義在于:JVM能夠根據處理器的特性(CPU的多級緩存系統、多核處理器等)適當 的重新排序機器指令,使機器指令更符合CPU的執行特點,最大限度的發揮機器的性能。
重排序的背景
我們知道現代CPU的主頻越來越高,與cache的交互次數也越來越多。當CPU的計算速度遠遠超過訪問cache時,會產生cache wait,過多的cache ?wait就會造成性能瓶頸。
針對這種情況,多數架構(包括X86)采用了一種將cache分片的解決方案,即將一塊cache劃分成互不關聯地多個 slots (邏輯存儲單元,又名?Memory Bank?或 Cache Bank),CPU可以自行選擇在多個 idle bank 中進行存取。這種?SMP?的設計,顯著提高了CPU的并行處理能力,也回避了cache訪問瓶頸。
Memory Bank的劃分
一般 Memory bank 是按cache address來劃分的。比如 偶數adress 0×12345000?分到 bank 0, 奇數address 0×12345100?分到 bank1。
重排序的種類
編譯期重排。編譯源代碼時,編譯器依據對上下文的分析,對指令進行重排序,以之更適合于CPU的并行執行。
運行期重排,CPU在執行過程中,動態分析依賴部件的效能,對指令做重排序優化。
二、 happens-before規則
Java存儲模型有一個happens-before原則,就是如果動作B要看到動作A的執行結果(無論A/B是否在同一個線程里面執行),那么A/B就需要滿足happens-before關系。
(1)同一個線程中的每個Action都happens-before于出現在其后的任何一個Action。
(2)對一個監視器的解鎖happens-before于每一個后續對同一個監視器的加鎖。
(3)對volatile字段的寫入操作happens-before于每一個后續的同一個字段的讀操作。
(4)Thread.start()的調用會happens-before于啟動線程里面的動作。
(5)Thread中的所有動作都happens-before于其他線程檢查到此線程結束或者Thread.join()中返回或者Thread.isAlive()==false。
(6)一個線程A調用另一個另一個線程B的interrupt()都happens-before于線程A發現B被A中斷(B拋出異常或者A檢測到B的isInterrupted()或者interrupted())。
(7)一個對象構造函數的結束happens-before與該對象的finalizer的開始
(8)如果A動作happens-before于B動作,而B動作happens-before與C動作,那么A動作happens-before于C動作。
三、 理解
而指令重排序又會對沒有依賴的兩個操作進行重排序,這不是相互矛盾的么? ? ? ?經過網上翻閱了一些資料以后,我的理解是,happens-before規則是用來判斷一個動作對另一個動作是否可見的法則,他只是用來判斷可見性的,而不是決定執行順序的,就是說動作A和動作B 的執行順序是可以通過指令重排發生變化的,而如果你要保證A和B的可見性關系,就必須采用其他控制手段來保證AB的執行順序不被打亂,這樣就能用happens-before規則來判斷AB兩個動作的可見性。? 參考信息: http://www.infoq.com/cn/articles/java-memory-model-2?utm_source=infoq&utm_medium=related_content_link&utm_campaign=relatedContent_articles_clk http://www.blogjava.net/xylz/archive/2010/07/03/325168.html
轉載于:https://www.cnblogs.com/vipper/p/3307991.html
總結
以上是生活随笔為你收集整理的happens-before规则和指令重排的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一步一步深入spring(6)--使用基
- 下一篇: 视觉库—OpenCV