1. 程式人生 > >多線程編程,CPU是如果解決多線程內存訪問問題的

多線程編程,CPU是如果解決多線程內存訪問問題的

這份 adding lock mes body 進行 後繼 圖片 share

CPU對內存變量的修改是先讀取內存數據到CPU Cache中,然後再由CPU做運算,運算完成後繼續寫入到內存中

技術分享圖片

在單核CPU中,這完全沒有問題,然而在多核CPU中,每一個CPU核心都擁有自己獨立的Cache

此時同時訪問同一個內存地址時,將會把內存值復制到多個CPU的Cache中

此時如果對Cache中的值進行修改數據就將會不一致,寫入到內存時,內存中的數據就將會達不到預期值

技術分享圖片

為了解決這一個問題,早期CPU中,采用了總線LOCK的辦法,某個CPU要對內存操作的時候,總線進行LOCK,直到操作完成再UNLOCK

總線包含了許多設備的控制,LOCK將會大大降低資源處理的速度,於是intel提出了MESI協議

intel自從奔騰之後就開始引入MESI協議,目前許多CPU都在使用該協議的變種

MESI中,一個Cache被稱為Row,不同CPU Cache中同一個內存地址的副本,他們的row都是相同的

Row有4種狀態,他們分別是

狀態

描述

M(Modified)

這行數據有效,數據被修改了,和內存中的數據不一致,數據只存在於本Cache中。

E(Exclusive)

這行數據有效,數據和內存中的數據一致,數據只存在於本Cache中。

S(Shared)

這行數據有效,數據和內存中的數據一致,數據存在於很多Cache中。

I(Invalid)

這行數據無效。

Exclusive獨占

技術分享圖片

M修改狀態

技術分享圖片

每個CPU在讀寫自己的Cache row的同時,也會監聽其他CPU的Cache row

當只有一個CPU擁有內存副本時,設置為E(Exclusive)狀態

當第二個CPU讀取內存副本時,設置為S(Shared)狀態

當其他CPU修改內存副本時,設置為I(Invalid)狀態

當前CPU修改內存副本時,設置為M(Modified)狀態

每個CPU Cache row都有自己的一個狀態

MESI狀態之間的遷移過程如下:

當前狀態

事件

行為

下一個狀態

I(Invalid)

Local Read

如果其它Cache沒有這份數據,本Cache從內存中取數據,Cache line狀態變成E;

如果其它Cache有這份數據,且狀態為M,則將數據更新到內存,本Cache再從內存中取數據,2個Cache 的Cache line狀態都變成S;

如果其它Cache有這份數據,且狀態為S或者E,本Cache從內存中取數據,這些Cache 的Cache line狀態都變成S

E/S

Local Write

從內存中取數據,在Cache中修改,狀態變成M;

如果其它Cache有這份數據,且狀態為M,則要先將數據更新到內存;

如果其它Cache有這份數據,則其它Cache的Cache line狀態變成I

M

Remote Read

既然是Invalid,別的核的操作與它無關

I

Remote Write

既然是Invalid,別的核的操作與它無關

I

E(Exclusive)

Local Read

從Cache中取數據,狀態不變

E

Local Write

修改Cache中的數據,狀態變成M

M

Remote Read

數據和其它核共用,狀態變成了S

S

Remote Write

數據被修改,本Cache line不能再使用,狀態變成I

I

S(Shared)

Local Read

從Cache中取數據,狀態不變

S

Local Write

修改Cache中的數據,狀態變成M,

其它核共享的Cache line狀態變成I

M

Remote Read

狀態不變

S

Remote Write

數據被修改,本Cache line不能再使用,狀態變成I

I

M(Modified)

Local Read

從Cache中取數據,狀態不變

M

Local Write

修改Cache中的數據,狀態不變

M

Remote Read

這行數據被寫到內存中,使其它核能使用到最新的數據,狀態變成S

S

Remote Write

這行數據被寫到內存中,使其它核能使用到最新的數據,由於其它核會修改這行數據,

狀態變成I

I

多線程編程,CPU是如果解決多線程內存訪問問題的