1. 程式人生 > >深入理解volatile關鍵字的作用(一)

深入理解volatile關鍵字的作用(一)

(一)計算機記憶體模型

大家都知道在計算機執行程式的時候每條指令都是在cpu中執行的,那麼執行指令的同時勢必會有讀取和寫入的操作,那麼這樣就引申出了一個問題。那麼在程式執行時資料的儲存是在計算機中的主存中(實體記憶體)的而記憶體的讀取和寫入的速度與cpu的執行指令速度相比差距是很大的,這樣就造成了與記憶體互動時程式執行效率大大降低,因此在cpu中就有了快取記憶體。

 也就說計算機cpu在執行指令時將主存中的資料複製到快取記憶體中,將結果運算完畢後在將運算結果重新整理到主存中。廢話不多說看圖說話

計算機cpu與主存互動

那麼大家也看到了計算機cpu會將運算資料複製到快取記憶體中。但是這樣如果在單執行緒是沒有問題的(單核多執行緒也是有問題的)本次只是針對多核多執行緒討論so 不廢話舉個栗子

i=i+1;

當同時有兩個執行緒執行這段程式碼其實我們想得到的結果是2但是呢計算機cpu可不會按照你想的來,其實它會這樣執行,假設我們現在有AB兩個執行緒,同時讀取了這段程式碼(假設i變數初始值為0),同時將變數複製到了快取記憶體,A執行緒將資料執行完畢後將變數重新整理到主存中i=1,而B執行緒也同時執行完畢將變數也重新整理到主存中i=1,但是AB變數在運算時讀取的都是快取記憶體的,AB執行緒的快取記憶體是互相不知道其中的值的,那麼這樣就引申出了快取一致性問題。

為了解決快取一致性問題有兩種解決辦法:

(1)通過匯流排加LOCK鎖的方式

(2)通過快取一致協議

早期的cpu中是通過在匯流排加鎖來解決快取不一致的,因為計算機cpu通訊是通過匯流排來執行的,如果在總線上面加鎖的話就阻塞來其他cpu對該變數的訪問,如上面的程式碼在程式執行時匯流排發出lock指令,那麼只有在這段程式碼執行完畢後其他cpu才能讀取變數執行相應的指令,這樣就解決了快取一致性問題。

但是上面的方式會有一個問題,由於在鎖住匯流排期間,其他CPU無法訪問記憶體,導致效率低下。

所以就出現了快取一致性協議。最出名的就是Intel 的MESI協議,MESI協議保證了每個快取中使用的共享變數的副本是一致的。它核心的思想是:當CPU寫資料時,如果發現操作的變數是共享變數,即在其他CPU中也存在該變數的副本,會發出訊號通知其他CPU將該變數的快取行置為無效狀態,因此當其他CPU需要讀取這個變數時,發現自己快取中快取該變數的快取行是無效的,那麼它就會從記憶體重新讀取。

未完待續