CPU多級緩存 MESI-CPU緩存一致性協議 以及 亂序執行優化

一、CPU的多級緩存

1.爲什麼需要CPU緩存

在一個典型的系統中,可能會有幾個緩存共享主存,每個相應的CPU會發出讀寫請求,CPU的頻率太快了,快的主存跟不上,這樣主存常常需要等待主存,而緩存的目的是爲了減少CPU讀寫共享主存的次數,解決CPU和主存速度不匹配的問題。

2.CPU緩存有什麼意義

時間局部性:如果某個數據被訪問,那麼不久的將來它有可能會再次被訪問。
空間局部性:如果某個數據被訪問,那麼與它相鄰的數據有可能很快也會被訪問。

二、MESI CPU緩存行的四種狀態

1.M:被修改(Modified)

該緩存行只被緩存在該CPU的緩存中,並且是被修改過的,即與主存中的數據不一致,該緩存行中的內存需要在未來的某個時間點(允許其他CPU讀取主存中相應內存之前)寫回主存中。當被寫回到主存中之後,該緩存行會變成E(獨享)狀態。

2.E:獨享的(Exclusive)

該緩存行只被緩存在該CPU的緩存中,他是未被修改過的,與主存中的數據一致。該狀態可以在任何時刻當有其它CPU讀取該內存時變成S(共享)狀態。同樣的當有CPU修改該緩存行的內容時,該狀態可以變成M(修改)狀態。

3.S:共享的(Shared)

該狀態意味着緩存行可能被多個CPU緩存,並且與主存數據一致,當有一個CPU修改該緩存行時,其它CPU該緩存行被作廢,變爲I(無效)狀態。

4.I:無效的(Invalid)

該緩存是無效的(可能有其它CPU修改了該緩存行)。

三、四種狀態的轉換關係

一個緩存行除了在Invalid狀態都可以滿足CPU的讀請求,而Invalid狀態必須從主存中讀取(變成S或者E狀態)來滿足CPU的讀操作。

一個寫請求只有在該緩存行是M或者E狀態才能被執行,如果緩存行處於S狀態,必須先將其它的緩存行中的該緩存行變成Invalid狀態(不允許不同CPU同時修改同一個緩存行,即使是不同位置的數據也不允許)。該操作經常作用廣播的方式完成,例如:Request For Ownership.

緩存可以隨時將一個非M狀態的緩存行作廢,或者變成Invalid狀態,而一個M狀態的緩存行必須先被寫回主存。

一個處於M狀態的緩存行必須時刻監聽所有試圖讀該緩存行對應於主存的操作,這種操作必須在緩存將該緩存行寫回主存,並將狀態變成S狀態之前延遲執行。

一個處於S狀態的緩存行也必須監聽其他緩存行使該緩存行無效或者獨享該緩存行的請求,並將該緩存行變成無效(Invalid)

一個處於E狀態的緩存行也必須監聽其它緩存讀主存中該緩存行的操作,一旦有這種操作,該緩存行需要變成S狀態。

對於M和E狀態而言總是精確的,他們在和該緩存行的真正狀態是一致的。而S狀態可能是非一致的,如果一個緩存將處於S狀態的緩存行作廢了,而另一個緩存實際上可能已經獨享了該緩存行,但是該緩存卻不會將該緩存行升遷爲E狀態,這是因爲其它緩存不會廣播他們作廢掉該緩存行的通知,同樣由於緩存並沒有保存該緩存行的copy的數量,因此(即使有這種通知)也沒有辦法確定自己是否已經獨享了該緩存行。

從上面的意義看來E狀態是一種投機性的優化:如果一個CPU想修改一個處於S狀態的緩存行,總線事務需要將所有該緩存行的copy變成invalid狀態,而修改E狀態的緩存不需要使用總線事務。

在這裏插入圖片描述
**  Local read:讀取主存中的數據到本地
  Local write:對本地的數據進行修改
  Remote read:別的緩存行從主存中讀取
  Remote write:別的緩存行對數據修改
**

當前狀態 事件 行爲 下一狀態
I Local read 1.如果其他緩存行沒有這份數據,該緩存行從主存中讀取,變爲E2.如果其他緩存行有這個數據,且狀態爲M,則先將數據更新到主存,該緩存行那個再從主存中取數據,所有緩存行變成S3.如果其他緩存行有這份數據且爲E或S,則本緩存行從主存中讀取,所有狀態都變成S E/S
I Local write 1.從主存中讀取,再對本地數據修改,狀態變成M。如果其它緩存行有該數據且爲M,則先將數據更新到內存。2.如果其他緩存行有該數據,則狀態都變成I M
I Remote read 是無效的,別的操作與其無關 I
I Remote write 是無效的,別的操作與其無關 I
當前狀態 事件 行爲 下一狀態
E Local read 從該狀態行取數據,狀態不變 E
E Local write 修改該緩存行的數據,狀態變爲M M
E Remote read 數據和別的緩存行公用,狀態變成S S
E Remote write 數據被修改,該緩存行狀態變成I I
當前狀態 事件 行爲 下一狀態
S Local read 從該狀態行取數據,狀態不變 S
S Local write 修改緩存行的數據,狀態變成M,其它緩存行狀態變成I M
S Remote read 狀態不變 S
S Remote write 數據被其它緩存行修改,該緩存行狀態變成I I
當前狀態 事件 行爲 下一狀態
M Local read 從該狀態行取數據,狀態不變 M
M Local write 再次修改該緩存行的數據,狀態不變 M
M Remote read 這個緩存行數據會先被寫回到主存,使其它緩存行能得到最新的數據,狀態變爲S S
M Remote write 先把數據寫回主存,由於其它緩存行修改了數據,該緩存行變爲I I

四、MESI協議的缺點

首先,在MESI協議中,修改一個處於S狀態的緩存行數據是十分麻煩的要經過以下幾個步驟。

1.本緩存行會先通過寄存器控制器向遠程擁有相同緩存行的寄存器發送一個RFO請求,告訴其它CPU把相同緩存的值變成Invalid狀態,等待收到各個緩存的(valid ack)已經完成無效狀態修改迴應。

2.把自己的狀態修改成E狀態,之後再修改數據。

3.修改之後再把自己的狀態修改成M狀態,數據寫入緩存行。

從以上的步驟可以看出,CPU會有一個等待的過程,而這個過程就會導致CPU的阻塞,無法充分利用CPU,這個時候就出現了數據緩存區。

1.數據緩存區

當修改一個變量的時候,執行修改操作不直接針對於緩存行,而是針對於一個storeBuffer的位置來操作的。這樣當CPU執行修改操作的時候,直接把數據寫入到storeBuffer裏,併發出廣播告知其他CPU,需要將緩存行變爲Invalid狀態,然後執行其他操作,等待接收到valid ack時纔會把storeBuffer中的內容寫到緩存行中。

但是緩存區的大小是有限的,如果緩存區的空間滿了,那麼依然需要等待valid ack的返回纔可以繼續運算。爲了優化這一段時間CPU的空閒時間,就出現了無效隊列。

2.無效隊列

無效隊列的作用就是當CPU接收到validate的廣播時,馬上給對方返回valid ack響應。等待當前的操作執行完再回來真正把緩存中的值變爲Invalid狀態。

四、數據緩存區和無效隊列造成的問題

1.導致內存重排:

(1)數據緩存區:當一個線程執行完修改操作時把數據寫入數據緩存區,這個時候另個一線程讀取了數據還是沒有被修改過的數據,並對其進行了操作,這個時候就發生了重排得到問題。

(2)無效隊列:當一個緩存行修改完成後,由於無效化隊列的存在,就會造成有些應該是Invalid狀態的緩存行還可以被其他線程所讀取,而此時讀取到的數據實際上是無效的舊數據。

2.導致不可見性問題:

(1)寫緩衝器暫存的數據,其他的執行處理器無法見。

(2)無效化隊列存在未執行的,其他執行處理器獲取數據來自於他本身的高速緩存當中。

CPU多級緩存 – 亂序執行優化

  處理器爲了提高運算速度而作出違背代碼原有順序的優化。如圖所示,代碼的順序是先執行a=10再執行b=20,而實際上有可能是恰恰相反的。
在這裏插入圖片描述
  顯然,在單核情況下這種優化是不會影響到執行的結果的,但是在多核環境下有可能會出現問題。在有多核以及多級緩存存在的情況下,邏輯上後寫入主存的數據未必真正後寫入,這就有可能造成數據上出現一定的問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章