Java併發 快取一致性

2021-09-01 16:15:30 字數 4048 閱讀 8677

cpu的時鐘頻率非常的快,跑起來的速度遠遠超過了記憶體、硬碟。《碼農翻身》形象的比喻cpu為阿甘,跑的速度是記憶體的100倍,硬碟的1000多萬倍。如果直接靠cpu直接和記憶體打交道,那麼cpu要等待太久,浪費資源。

我們平時編寫的程式中,包含著很多連續建立的陣列、物件,各種迴圈、遞迴、呼叫同一函式等,其實本質上符合了區域性性原理區域性性原理具體是指在cpu訪問儲存裝置時,無論是訪問資料還是訪問指令,都趨於聚集在一片連續的區域中,主要包含時間與空間上的區域性性。

有了這樣的特性,就可以在cpu和記憶體之間新增快取記憶體儲存cpu經常訪問的資料,如下圖所示,緩解cpu和記憶體速度嚴重差異的問題。

cpu和cache之間進行資料/指令訪問,而記憶體(主存)和快取記憶體則通過系統匯流排來實現通訊。程式設計師編寫的程式以及資料被載入到記憶體中後,隨後被載入到快取記憶體,cpu執行完指令處理完資料將結果寫回快取記憶體中,最後快取記憶體再寫回記憶體。

然而,由於cpu的運算速度不斷提公升,很快超越了一級快取的資料 i\o 能力,cpu廠商們又開始引入了多級的快取結構。多核的cpu至少擁有著不止乙個一級快取,當快取記憶體中拷貝了記憶體中同乙個資料多個副本時,cpu操作的是每乙個副本,而如何保證副本與副本之間,以及副本與主存的資料一致呢?

主要利用的是快取一致性的原則。

狀態含義

監聽任務

m被修改

modified

因為快取行剛被修改,資料應是獨一無二的,與主存中的資料不一致,與其他cpu的快取中對應資料也不相同。但是一定會在將來某個時間點寫回主存中,這個時間點一定是在其他cpu讀取自己的(主存相應的)快取之前。

被修改的快取行必須時刻監聽所有想讀該快取行對應的主存/其他cpu快取的操作,因為要確保在cpu讀取操作之前把被修改的快取行寫回主存並將狀態變為 s。

e獨享的

exclusive

被修改狀態的快取行要將資料寫回主存,此時可以認為是獨享的狀態。只有自己的快取和主存中資料一致,其他cpu對應的快取行還沒有更新。但是一定會在將來其他cpu讀取對應的快取行之前變為共享狀態。

獨享的快取行也必須監聽其他cpu快取讀取主存中對應快取行的操作,一旦有了這種操作,該快取行需要變成 s 狀態。

s共享的

shared

該狀態意味該快取行可能被多個cpu快取,並且各個快取中的資料與主存中的資料是一致的。當有乙個cpu修改了該快取行中的資料,該快取行變為被修改狀態,其他cpu中對應的快取作廢,變為無效狀態 i。

對於該快取行來說,要監聽其他快取使該快取行無效。

i無效的

invalid

快取行作廢,無效。

\本地快取當前狀態

事件行為

本地快取狀態變化

觸發快取行狀態變化

其他快取行狀態變化

m本地快取讀取本地快取資料

從本地快取讀取資料,狀態不變。觸發快取就是本身。其他快取則因為本地快取是

m,早就是i了。

m->m

m->m

i本地快取寫入本地快取資料

本地快取行狀態為

m,繼續修改資料,狀態還是

m。觸發快取就是本身。其他快取則因為本地快取是

m,早就是i了。

m->m

m->m

i觸發快取讀取本地快取對應資料

觸發快取行和其他快取行狀態都為

i,觸發快取行想要讀取對應資料,必然得從主存走。本地快取行中資料將回寫到主存,本地狀態變為

e。等到觸發快取從主存中獲取到資料,所有快取行都同步,狀態變為s。

m->e->s

i->s

i->s

觸發快取寫入本地快取對應資料

觸發快取行想要先寫對應快取,發現本地快取資料還沒同步,所有先走觸發快取讀取本地快取對應資料的流程。由於觸發快取要寫入資料,所以本地快取和其他快取會變為i,此時觸發快取行狀態相當於e,等觸發快取寫入成功最後會變為m,。

m->e->s->i

i->s->e->m

i->s->i

e本地快取讀取本地快取資料

從本地快取讀取資料,狀態不變。觸發快取就是本身。其他快取則因為本地快取是

e,早就是i了。

e->e

e->e

i本地快取寫入本地快取資料

本地快取行已經回寫到主存,又繼續修改,狀態又變為

m,其他快取行繼續

i。觸發快取就是本身。

e->m

e->m

i觸發快取讀取本地快取對應資料

本地快取行已經回寫到主存,觸發快取讀取資料之前需要先進行本地快取行資料的同步,所有快取行資料變為s。同步完成,觸發快取行也就正好讀完。

e->s

i->s

i->s

觸發快取寫入本地快取對應資料

觸發快取行想要寫對應資料,先經歷觸發快取讀取本地快取對應資料的過程。當共享完成,觸發快取行對資料進行更新,其他快取行都變為i,隨後自身變為e再變為m。

e->s->i

i->s->e->m

i->s->i

s本地快取讀取本地快取資料

共享狀態讀取不影響。ss

s本地快取寫入本地快取資料

共享狀態下,本地快取進行修改,其他快取行將先變成

i,此時相當於本地快取行為

e,修改後再變成

m。觸發快取就是本地快取。

s->e->m

s->e->m

s->i

觸發快取讀取本地快取對應資料

共享狀態讀取不影響。ss

s觸發快取寫入本地快取對應資料

共享狀態下,觸發快取想要修改,則本地快取和其他快取先變為

i,觸發快取則變成

e。修改完成後,觸發快取繼續變成m。

s->i

s->e->m

s->i

i本地快取讀取本地快取資料

1. 如果其他快取沒有對應資料,狀態為

i,本地快取從主存讀取資料,快取行變成e;

2. 如果其他快取有對應資料,且狀態為

m,則先將資料更新到主存,本地快取再從主存中讀取,兩個快取對應的快取行都變為s;

3. 如果其他快取有對應資料,且狀態為

s/e,意味著主存已經更新,可以直接讀取,這時兩個快取對應的快取行都變為s。

i->e

i->s

i->s

i->e

i->s

i->s

i->i

m->e->s

e->s/s->s

本地快取寫入本地快取資料

1. 如果其他快取沒有對應資料,一開始所有快取行都為無效,所以需要先從主存中取資料同步,寫入所有快取,快取行狀態變為

e。隨後進行本地快取更新,狀態變為m;

2. 如果其他快取有資料但是快取行狀態為

e,本地快取行為無效,所以需要先從主存中取資料同步,寫入本地快取,快取行狀態變為

e。隨後進行本地快取更新,狀態變為m;

3. 如果其他快取中有對應資料,且狀態為

m,則先將其他快取中的資料更新到主存,本地快取再從主存中讀取,所有快取行都為

s。隨後進行本地快取更新,本地快取行狀態變為

m,其他快取變為i。

i->s->e->i

i->s->e->i

i->s->e->i

i->s->e->i

i->s->e->i

i->s->e->i

i->s->i

e->s->i

m->e->s->i

觸發快取讀取本地快取對應資料

既然是本地快取行是

i,觸發快取行的操作與它無關。i\

\觸發快取寫入本地快取對應資料

既然是本地快取行是

i,觸發快取行的操作與它無關。i\

\

快取一致性

一般應用而言,追求的都是快取的最終一致性。一般的快取系統,都是按照key去快取查詢,如果不存在對應的value,就應該去後端系統查詢 比如db 如果key對應的value是一定不存在的,並且對該key併發請求量很大,就會對後端系統造成很大的壓力。這就叫做快取穿透。引起這個問題的主要原因還是高併發的時...

快取一致性

計算機體系結構量化研究方法 第五版 學習筆記 快取一致性 1 快取一致性的問題 2 儲存器一致性的概念 3 一致性的基本實現方案 大型 多級快取可以充分降低處理器對儲存頻寬的需求。採用對稱共享儲存器的計算機通常支援對共享資料與專用資料的快取。多處理器之間的通訊基本上是通過讀寫共享資料實現。為了降低訪...

快取一致性協議

作業系統的cpu和記憶體並不是直接互動操作的。我們的cpu有一級快取,cpu直接操作一級快取,由一級快取和記憶體進行互動。所以同乙個程式,cpu進行切換的時候,切換前和切換後的資料可能會有不一致的情況。那麼這個就是乙個很大的問題了。如何保證各個cpu快取中的資料是一致的。就是cpu的快取一致性問題。...