- 計算機內存:
計算機CPU(central processing unit)和內存的交互是最頻繁的,內存是我們的高速緩存區。用戶磁盤和CPU的交互,而CPU運轉速度越來越快,磁盤遠遠跟不上CPU的讀寫速度,才設計了內存,用戶緩存用戶IO等待導致CPU的等待成本。但是隨着CPU的發展,內存的讀寫速度也遠遠跟不上CPU的讀寫速度,因此,為了解決這一糾紛,CPU廠商在每顆CPU上加入了高速緩存,用來緩解這種症狀。因此CPU與內存的交互如下圖:
同樣,我們知道單核CPU的主頻不可能無限增長,想要提升性能,需要多個處理器協同工作,Intel總裁貝瑞特單膝下跪事件標識着多核時代的到來。
基於高速緩存的存儲交互很好的解決了處理器與內存之間的矛盾,也引入了新的問題:緩存一致性問題。在多處理器系統中,每個處理器有自己的高速緩存,而他們又共享同一塊內存(主存),當多個處理器運算都涉及到同一塊內存區域的時候,就有可能出現緩存不一致的問題。為了解決這一問題,需要各個處理器運行時都遵守一些協議,在運行時將需要這些協議保存數據的一致性。協議包括:MSI/MESI/MOSI/Synapse/Firely/DragonProtocol等,如下圖:
簡述下圖的總線鎖機制,CPU和其他部件通信是通過總線進行,如果在總線加LOCK鎖的話,也就是阻塞了其他CPU對其他部件的訪問(如內存),從而使得只能有一個CPU能使用這個變量的內存
由於在鎖住總線期間,其他CPU無法訪問內存,導致效率低下。
所以就出現了緩存一致性協議。最出名的就是Intel 的MESI協議,MESI協議保證了每個緩存中使用的共享變量的副本是一致的。它核心的思想是:當CPU寫數據時,如果發現操作的變量是共享變量,即在其他CPU中也存在該變量的副本,會發出信號通知其他CPU將該變量的緩存行置為無效狀態,因此當其他CPU需要讀取這個變量時,發現自己緩存中緩存該變量的緩存行是無效的,那么它就會從內存重新讀取。
- JVM內存:
Java虛擬機內存模型中定義的訪問操作和物理計算機處理的基本一直,如圖:
JAVA中通過多線程機制使得多個任務同時執行處理,所有的線程共享JVM內存區域主存,而每一個線程又單獨有自己的工作內存,當線程與內存區域進行交互時,數據從主存拷貝到工作內存,進而交由線程處理(操作碼+操作數)
為了或得較好的執行性能,JAVA內存模型並沒有限制執行引擎使用處理器的寄存器或者高速緩存來提升指令執行速度,也沒有限制編譯器對指令進行重排序。
也就是說,在JAVA內存模型中,也會存在緩存一致性問題和指令重排序問題