緩存架構
現代CPU都有多個核及多級緩存L1、L2、L3等,其中L1一般是每個核專用的,考慮簡化的模型如下圖:

一致性問題
假設CPU0 CPU1同時讀了內存中的某段內容x=0,這時它們的緩存中都有該內容的副本0,然后CPU0將x的內容改為1,如下圖:

這時如果CPU1需要再去訪問x的值,但這時緩存中有x的值0,這時得到的值是舊值,也就出現了緩存不一致的情況。
顯然,我們需要某種方法,當CPU0修改了x的內容時,需要使得其它緩存中能夠同步,一種實現方法是硬件監聽總線,當CPU0更新了緩存時會向總線廣播消息通知其它CPU,當CPU1收到廣播事件時,檢查是否有相同的數據副本在自己的緩存中,如果有的話需要更新對應的緩存行的狀態。
MESI協議
一種廣泛使用的一致性協議是MESI協議,每個緩存行有4種狀態,MESI是指4種狀態的首字母,分別為:
| 狀態 | 描述 | 監聽任務 |
|---|---|---|
| M 修改 (Modified) | 該Cache line有效,數據被修改了,和內存中的數據不一致,數據只存在於本Cache中。 | 緩存行必須時刻監聽所有試圖讀該緩存行相對就主存的操作,這種操作必須在緩存將該緩存行寫回主存並將狀態變成S(共享)狀態之前被延遲執行。 |
| E 獨享、互斥 (Exclusive) | 該Cache line有效,數據和內存中的數據一致,數據只存在於本Cache中。 | 緩存行也必須監聽其它緩存讀主存中該緩存行的操作,一旦有這種操作,該緩存行需要變成S(共享)狀態。 |
| S 共享 (Shared) | 該Cache line有效,數據和內存中的數據一致,數據存在於很多Cache中。 | 緩存行也必須監聽其它緩存使該緩存行無效或者獨享該緩存行的請求,並將該緩存行變成無效(Invalid)。 |
| I 無效 (Invalid) | 該Cache line無效。 | 無 |
我們可以將MESI看成有限狀態機:

模擬運行
- 初始狀態CPU0~CPU3的L1 cache全為空,都處於I(Invalid)狀態。
- CPU0讀x的值,這是一次本地讀,由於本地L1沒有緩存數據x,這時會向總線發出讀信號,看其它L1 cache是否有數據,由於其它cache這時也為空,因此只能向主存讀取x的值並存在自己的緩存行中,並把狀態改為E(Exclusive)
- CPU1讀x的值,由於只有CPU0的緩存上有,因此CPU0把x的值發給CPU1,這時CPU0和CPU1都將緩存行的狀態改為S(Shared)
- CPU2更新x的值,這時CPU2的緩存為空,會向總線詢問其它CPU是否有緩存該數據。這時CPU0和CPU1發現自己都緩存了該數據,就將緩存行的狀態改為I,CPU2收集完其它CPU的應答后,把CPU2的緩存行狀態改為M(Modified).
