高速快取一致性協議MESI與記憶體屏障

一、CPU高速快取簡單介紹

  CPU高速快取機制的引入,主要是為了解決CPU越來越快的運行速度與相對較慢的主存訪問速度的矛盾。CPU中的暫存器數量有限,在執行記憶體定址指令時,經常需要從記憶體中讀取指令所需的數據或是將暫存器中的數據寫回記憶體。而CPU對記憶體的存取相對CPU自身的速度而言過於緩慢,在記憶體存取的過程中CPU只能等待,機器效率太低。

  為此,設計者在CPU與記憶體之間引入了高速快取。CPU中暫存器的存儲容量小,訪問速度極快;記憶體存儲容量很大,但相對暫存器而言訪問速度很慢。而高速快取的存儲大小和訪問速度都介於二者之間,作為一個緩衝橋樑來填補暫存器與主存間訪問速度過大的差異。

  引入高速快取後,CPU在需要訪問主存中某一地址空間時,高速快取會攔截所有對於記憶體的訪問,並判斷所需數據是否已經存在於高速快取中。如果快取命中,則直接將高速快取中的數據交給CPU;如果快取未命中,則進行常規的主存訪問,獲取數據交給CPU的同時也將數據存入高速快取。但由於高速快取容量遠小於記憶體,因此在高速快取已滿而又需要存入新的記憶體映射數據時,需要通過某種演算法選出一個快取單元調度出高速快取,進行替換。

  由於對記憶體中數據的訪問具有局部性,使用高速快取能夠極大的提高CPU訪問存儲器的效率。

二、高速快取一致性問題

高速快取與記憶體的一致性問題

  高速快取在命中時,意味著記憶體和高速快取中擁有了同一份數據的兩份拷貝。CPU在執行修改記憶體數據的指令時如果高速快取命中,只會修改高速快取中的數據,此時便出現了高速快取與記憶體中數據不一致的問題。

  這個不一致問題在早期單核CPU環境下似乎不是什麼大問題,因為所有的記憶體操作都來自唯一的CPU。但即使是單核環境下,為了減輕CPU在I/O時的負載、提高I/O效率,先進的硬體設計都引入了DMA機制。DMA晶片在工作時會直接訪問記憶體,如果高速快取首先被CPU修改和記憶體不一致,就會出現DMA實際寫回磁碟的內容和程式所需要寫入的內容不一致的問題。

  為了更好的理解多核CPU環境下工作的MESI協議,這裡先簡單介紹單核環境下高速快取被首先改寫而導致cache與主存不一致問題的解決方案,簡單來說有兩種方法:通寫法回寫法

通寫法(Write Through):

  即CPU在對cache寫入數據時,同時也直接寫入主存,這樣就能使得主存和cache中的數據始終保存一致。

  通寫法的優點是簡單,硬體上容易實現,同時在調度快取單元時不會有臟數據,調度速度快;缺點是每次cache寫入操作時都增加了寫主存的等待時間,效率較低。

回寫法(Write Back):

  回寫法和通寫法的主要區別在於,回寫法在CPU寫cache時並不實時同步寫主存,而是在進行調度被覆蓋前整體的寫回主存。如果被調度出的cache單元並沒有被寫入過,則直接被覆蓋無需寫回主存。

  回寫法的優點是寫入cache時無需同步主存,總體效率比通寫法高。缺點是硬體實現較為複雜。

多核CPU高速快取間的一致性問題

  隨著單核主頻速度的增長受到制約,CPU的發展由單核逐漸過度到了多核,目前主流的CPU都是多核心的。但隨著多核CPU提高電腦並發性能的同時,也帶來了一系列的問題,這其中就包括了多核CPU下的高速快取一致性問題

  在多核CPU的架構下,通常每一個核心都擁有著自己獨有的高速快取,每個核心能並發的讀寫自己的高速快取。高速快取可以有多個,但其對應的記憶體數據邏輯上卻只有一份,多核並發的修改其高速快取中同一記憶體的映射數據就會出現高速快取中的數據不一致的問題。如果不對多核CPU下的高速快取並發訪問施加一定的約束,那麼並發程式中對共享記憶體數據的存取就會出現問題,並發程式的正確性將無法得到有效保障

高速快取一致的存儲系統定義

  在討論解決高速快取一致性問題的方法前,我們需要更精確的定義什麼是高速快取一致性。

  記憶體系統的一個本質特徵是:一個記憶體系統應該能提供一組保存值的存儲單元,當對一個存儲單元執行讀操作時,應該能返回「最近」一個對該存儲單元的寫操作所寫入的值。在串列程式中,程式設計師利用記憶體來將程式中某一點計算出來的值,傳遞到該值的使用點,實際上就是利用了上述基本性質。同樣,運行在單處理器上的多個進程或執行緒利用共享地址空間進行通訊,實際上也是利用了記憶體系統的這個性質。

  一個讀操作應返回最近的向那個位置的寫操作所寫的值,而不管是哪個執行緒寫的。當所有的執行緒運行在同一個物理處理器上時,它們通過相同的高速快取層次來看記憶體,因此在這種情況下,高速快取不會引起問題。當在共享存儲的多處理器系統上運行一個具有多個執行緒的程式時,希望不管這些執行緒是運行在同一個處理器上,還是位於不同的處理器上,程式的運行結果都是相同的。

  上面摘抄自書上的概念描述有些晦澀,我個人的理解是:按照程式指令的運行順序,對於同一記憶體單元內容(變數值)能夠令後面的讀操作讀取到之前最近寫操作後的結果,保證程式邏輯序的正確性。這一順序性的保證在單核環境下不是問題,因為所有的指令順序都使用同一個高速快取,但在多核多高速快取副本的情況下運行某一程式的多個並發任務時就會出現問題,因為並沒有約定多個處理器核心對同一存儲單元並發操作時的全局順序,即「最近」這一概念是模糊、不明確的。

  因此,一個高速快取一致的存儲系統其首先要滿足的一個條件便是:根據一個程式的任意一次執行結果,都能夠對每個記憶體單元的存取操作構造出邏輯上的全局串列序列(即使是多核體系下,對記憶體的存取邏輯上也要強制串列化)。這一全局邏輯串列序列還需要滿足額外的兩個條件:一是同一處理器所發出的程式記憶體存取指令順序(程式邏輯序),與在全局邏輯串列序列中的先後順序保持一致;二是每個讀操作的值,返回的是在全局邏輯串列序列中最近的寫操作之後的值。

  上述高速快取一致性的定義隱含了在多核環境下的兩個重要性質:一是寫傳播,二是寫串列化

  寫傳播(Write Propagation):一個處理器對一個位置的所寫入的值,最終對其它處理器是可見的。

  寫串列化(Write Serialization):對同一記憶體單元的所有寫操作(無論是來自一個處理器還是多個處理器)都能串列化。換句話說,所有的處理器能以相同的次序看到這些寫操作。

三、MESI高速快取一致性協議

  通常多核並行架構的CPU,每個核雖然都獨自工作,但與外部存儲器的交互依然是共用同一匯流排進行的。通過匯流排,每個核心都能夠監聽、接收到來自其它核心的消息通知,這一機制被稱為匯流排偵聽或是匯流排嗅探

基於匯流排偵聽的寫傳播:

  每個核心在對自己獨有的高速快取行進行修改時,需要將修改通知送至匯流排進行廣播。其它核心在監聽到匯流排上來自其它核心的遠程寫通知時,需要查詢本地高速快取中是否存在同樣記憶體位置的數據。如果存在,需要選擇將其設置為失效狀態或是更新為最新的值。

基於匯流排偵聽的寫串列化:

  匯流排上任意時間只能出現一個核的一個寫通知消息。多個核心並發的寫事件會通過匯流排仲裁機制將其轉換為串列化的寫事件序列(可以簡單理解為邏輯上的一個FIFO事件隊列),在每個寫事件廣播時,必須得到每個核心對事件的響應後,才進行下一個事件的處理,這一機制被稱作匯流排事務

  而本文的主角MESI協議便是基於匯流排偵聽機制,採用回寫法、寫傳播失效策略的高速快取一致性協議,其另一個更精確的名稱是四態快取寫回無效協議。

  下面介紹MESI協議是如何工作以實現多核間高速快取一致性的。

MESI協議快取行狀態介紹

  MESI四態快取寫回無效協議,為高速快取中的每個存儲單元行cache line賦予了一個狀態屬性,狀態類型共有4種:Modified(已被修改)、Exclusive(被獨佔)、Shared(被共享)、Invalid(無效),這也是MESI這一名稱的由來。

  任意時刻每個快取行都處於上述四種狀態的其中一種,並且可能會因為發生的快取事件而遷移至另一種狀態。

Modified:

  快取數據有效,在讀入快取後曾經被當前CPU修改過卻沒有寫回,導致與記憶體中的對應數據不一致

  記憶體中對應的數據只在本地核心的高速快取中存在,其它核的高速快取中並沒有快取這一記憶體數據。

  有效,本地cache獨佔,與記憶體數據不一致(被修改 Modified)。

Exclusive:

  快取數據有效,在讀入快取後沒有被當前CPU修改過與記憶體中的對應數據保持一致

  記憶體中對應的數據只在本地核心的高速快取中存在,其它核的高速快取中並沒有快取這一記憶體數據。

  有效,本地cache獨佔,與記憶體數據一致(被獨佔 Exclusive)。

Shared:

  快取數據有效,在讀入快取後沒有被當前CPU修改過與記憶體中的對應數據保持一致

  記憶體中對應的數據除了本地核心的高速快取中存在,其它核的高速快取中也快取了這一記憶體數據

  有效,與其它cache共享,與記憶體數據一致(被共享 Shared)。

Invalid:

  快取數據無效。無效的含義既代表著之前快取行有效,卻因為某些事件變為無效;也代表著對應快取行不存在。

  上述快取行的共享/獨佔狀態,指的是本地高速快取中存在有效的對應存儲單元快取行,而其它核的高速快取中不存在對應單元的內容或是對應的快取行是Invalid無效狀態。

  在MESI協議中不存在與Invalid無效可以視作是等價的

記憶體快取行的穩定態與非穩定態

  了解了MESI的四種記憶體快取行狀態後,下面引入快取記憶體行穩定態與非穩定態的概念。快取記憶體行的穩定態指的是多核下高速快取中的對應記憶體中在所有高速快取中數據是一致的;非穩定態是穩定態的反面,指的是多核高速快取中對應記憶體中在所有的高速快取中數據出現了不一致,有不同的副本值

  當處於穩定態的快取行由於某些事件的發生轉向不穩定態時,MESI協議能夠採取一些措施令整個多核存儲系統重新回到穩定態(可以類比自平衡二叉樹在發生插入/刪除事件時,引起失衡後進行的重平衡操作)。

記憶體快取行處於穩定態的幾種情況:

  1、對應記憶體行在所有核的高速快取中都不存在。

  2、對應記憶體行有且僅在一個核的高速快取中存在,其狀態可以是Exclusive也可以是Modified。

  3、對應記憶體行在一個以上核的高速快取中存在,每個快取行中的存儲的數據都和記憶體一致,其狀態都為Shared。

MESI協議快取事件

  隨著多核CPU中並發程式的不斷運行,高速快取被反覆的讀寫,快取記憶體行的狀態也會在MESI這四種狀態間反覆變化。

  在MESI協議中,抽象出了四種會導致快取記憶體行狀態的變化快取事件:本地讀、本地寫、遠程讀以及遠程寫。快取事件針對的是某一記憶體快取行的事件。

本地讀(Local Read):

  本地讀事件指的是本地核心對自己的快取行進行讀取。

本地寫(Local Write):

  本地寫事件指的是本地核心對自己的快取行進行寫入。

遠程讀(Remote Read):

  遠程讀事件指的是匯流排上的其它核心對某一記憶體快取行進行了讀取,當前核心監聽到的事件。

  某一個核心的本地讀事件,對於其他核心就是針對其對應記憶體快取行的遠程讀事件。

遠程寫(Remote Write):

  遠程寫事件指的是匯流排上的其它核心對某一記憶體快取行進行了寫入,當前核心監聽到的事件。

  某一個核心的本地寫事件,對於其他核心就是針對其對應記憶體快取行的遠程寫事件。

MESI協議快取行狀態遷移

  快取事件的發生可能會使得本地/遠程的對應快取行狀態發生變化。比如當原本處於獨佔狀態的本地快取行監聽到遠程讀事件時,需要將其由Exclusive被獨佔轉變為Shared被共享;當監聽到遠程寫事件時,如果發現對應的快取行存在(此時必定是Shared被共享狀態),此時的記憶體快取行便失去了穩定,MESI協議是採取的是寫無效策略,需要將本地對應的快取行設置為Invalid無效。

  MESI協議中的四種狀態在發生上述四種快取事件時都可能發生對應的狀態遷移,兩兩組合之後共有4*4=16種情況,下面進行詳細討論。

  本地讀/寫事件和其它核的遠程讀/寫事件是互相對應的,相互之間對照能更好的理解MESI協議的工作機制。

當前快取行處於Invalid狀態時:

發生local read本地讀事件:

  Invalid無效的快取行,在發生本地讀事件時,必須從記憶體或是處於Exclusive狀態的遠程高速快取中獲取對應的最新數據寫入本地快取。

  1.當其它核心中都不存在對應快取行數據時,從記憶體中獲取。載入後全局有且只有本地快取中有此快取行記錄,本地快取行的狀態由Invalid變成Exclusive。

  2.當其它的某一核心中恰好也存在對應快取行數據,且狀態為Exclusive或Shared時,從記憶體或是存在快取行的核心中獲取。此時由於本地和其它核心都保存了對應快取行數據,但不獨佔快取行,本地快取行的狀態由Invalid變成Shared。

  3.當其它的某一核心中恰好也存在對應快取行數據,且狀態為Modified時,觸發其遠程讀事件,將修改過的最新值寫入記憶體後,由本地核心從記憶體中讀取最新的值。此時由於本地和之前狀態為modified的核心都保存了對應快取行數據,本地快取行的狀態由Invalid變成Shared。

發生local write本地寫事件:

  Invalid無效的快取行,在發生本地寫事件時,必須從記憶體或是處於Exclusive狀態的遠程高速快取中獲取對應的最新數據寫入本地快取,再進行修改。

  1.當其它核心中都不存在對應快取行數據時,從記憶體獲取並修改。載入後全局有且只有本地快取中有此快取行記錄,由於修改過和記憶體中數據不同,本地快取行的狀態由Invalid變成Modified。

  2.當其它的某一核心中恰好也存在對應快取行數據時,且狀態為Exclusive或Shared時,從記憶體或是存在快取行的核心中獲取並修改。為了保持高速快取一致性的穩定,遠端的其它核心中的數據不能與本地核心本地寫的最新數據產生衝突,遠端的其它核觸發遠程寫事件,狀態都設置為Invalid(寫失效協議)。此時全局有且只有本地快取中有此快取行記錄,本地快取行的狀態由Invalid變成Modified。

  2.當其它的某一核心中恰好也存在對應快取行數據時,且狀態為Modified,觸發其遠程寫事件,將修改過最新值寫入記憶體後,由本地核心從記憶體中讀取最新的值並修改。遠端的核心(之前為modified)中的數據不能與本地核心本地寫的最新數據產生衝突,狀態設置為Invalid。此時全局有且只有本地快取中有此快取行記錄,本地快取行的狀態由Invalid變成Modified。

發生remote read遠程讀事件:

  Invalid無效狀態等價於快取行不存在,不對遠程讀事件進行任何處理,狀態依然為Invalid。

發生remote write遠程寫事件:

  Invalid無效狀態等價於快取行不存在,不對遠程寫事件進行任何處理,狀態依然為Invalid

當前快取行處於Exclusive狀態時:

發生local read本地讀事件:

  Exclucive代表本地核獨佔當前快取行。

  本地讀時直接從自己的高速快取中獲取數據即可,狀態不變,依然為Exclusive。

發生local write本地寫事件:

  Exclucive代表本地核獨佔當前快取行,且數據和記憶體中一致。

  本地寫會使得快取中的數據與記憶體不一致,但依然獨佔,狀態由Exclusive變為Modified。

發生remote read遠程讀事件:

  當監聽到遠程讀事件時,意味著當前快取行已經不再是獨佔狀態,而是共享狀態了,狀態由Exclusive變為Shared。

發生remote write遠程寫事件:

  當監聽到遠程寫事件時,意味著當前快取行的數據已經和本地快取中的數據不一致了,需要廢棄本地的快取行,狀態由Exclusive變為Invalid。

當前快取行處於Shared狀態時:

發生local read本地讀事件:

  Shared代表本地核心和遠程核心共享了快取行,且數據是最新的。本地讀時直接從自己的高速快取中獲取數據即可,狀態不變,依然為Shared。

發生local write本地寫事件:

  本地寫會觸發其它核的(處於Shared狀態)遠程寫事件,遠程核的狀態會被統一設置為無效,本地核心將獨佔這一快取行。由於本地寫使得快取行數據和記憶體不一致,狀態由Shared變為Modified

發生remote read遠程讀事件:

  當監聽到遠程讀事件時,其並沒有改變全局狀態下快取行的數據,狀態不變依然為Shared。

發生remote write遠程寫事件:

  當監聽到遠程寫事件時,意味著當前快取行的數據已經和本地快取中的數據不一致了,需要廢棄本地的快取行,狀態由Shared變為Invalid。

當前快取行處於Modified狀態時:

發生local read本地讀事件:

  Modified代表本地核心獨佔當前快取行,在全局串列寫序列中,本地讀事件讀取的依然是最新的值。本地讀時直接從自己的高速快取中獲取數據即可,狀態不變,依然為Modified。

發生local write本地寫事件:

  本地寫時依然獨佔快取行,且和記憶體中數據不一致,狀態不變,依然為Modified。

發生remote read遠程讀事件:

  當監聽到遠程寫事件時,為了使得其獲取到的值是全局串列序列中最近的值,需要先將Modified之後的最新值寫回記憶體,令最新值對其它核心可見。

  遠程讀事件意味著有其它核心共享了對應的快取行,本地不再獨佔,但數據依然和本地快取中的值保持一致,狀態由Modified變為Shared。

發生remote write遠程寫事件:

  當監聽到遠程寫事件時,為了使得其獲取到的值是全局串列序列中最近的值,需要先將Modified之後的最新值寫回記憶體,令最新值對其它核心可見。

  遠程讀事件意味著有其它核心共享了對應的快取行,本地不再獨佔,且本地快取的數據不再是最新的,需要令其失效,狀態由Modified變為Invalid。

四、MESI協議的優化與記憶體屏障

  通過MESI協議,在強制串列化的匯流排事務幫助下能夠始終保持一個全局高速快取一致的穩定狀態。

  MESI協議依賴匯流排偵聽機制,在某個核心發生本地寫事件時,為了保證全局只能有一份快取數據,要求其它核對應的快取行統統設置為Invalid無效狀態。為了確保匯流排寫事務的強一致性,發生本地寫的高速快取需要等到遠端的所有核心都處理完對應的失效快取行,返回Ack確認消息後才能繼續執行下面的記憶體定址指令(阻塞)。

原始MESI協議實現時的性能問題:

  1.對於進行本地寫事件的核心,遠端核心處理失效並進行響應確認相對處理器自身的指令執行速度來說是相當耗時的,在等待所有核心響應的過程中令處理器空轉效率並不高。

  2.對於響應遠程寫事件的核心,在其高速快取壓力很大時,要求實時的處理失效事件也存在一定的困難,會有一定的延遲。

  不進行優化的MESI協議在實際工作中效率會非常的低下,因此CPU的設計者在實現時對MESI協議進行了一定的改良。

存儲快取(Store Bufferes)

  針對上述本地寫事件需要等待遠端核心ACK確認,阻塞本地處理器的問題,引入了存儲快取機制。

  存儲快取是屬於每個CPU核心的。當使用了存儲快取後,每當發生本地寫事件時,本地核心不再阻塞的等待遠程核的確認響應,而是將寫入的新值放入存儲快取中,繼續執行後面的指令。存儲快取會替處理器接受遠端核心的ACK確認,當對應本地寫事件廣播得到了全部遠程核心的確認後,再提交事務,將其新值寫入本地高速快取中。存儲快取的大小是十分有限的,當堆積的事務滿了之後,依然會阻塞CPU,直到有事務提交釋放出新的空間。

  存儲快取的引入將本地寫事件—>等待遠程寫通知確認消息並提交這一事務,從同步、強一致性變成了非同步、最終一致性,提高了本地寫事件的處理效率。

  本地處理器在進行本地讀事件時,由於可能存儲快取中新修改的數據還未提交到本地快取中,這就會造成一個核心內,對於同一快取行其後續指令的讀操作無法讀取到之前寫操作的最新值。為此,在進行本地讀操作時,處理器會先在存儲快取中查詢對應記錄是否存在,如果存在則會從存儲快取中直接獲取,這一機制被稱為Store Fowarding

失效隊列(Invalid Queue)

  針對上述遠端核心響應遠程寫事件,實時的將對應快取行設置為Invalid無效狀態延遲高的問題,引入了失效隊列機制。

  失效隊列同樣是屬於每個CPU核心的。當使用了失效隊列後,每當監聽到遠程寫事件時,對應的高速快取不再同步的處理失效快取行後返回ACK確認資訊,而是將失效通知存入失效隊列,立即返回ACK確認消息。對於失效隊列中的寫失效通知,會在空閑時逐步的進行處理,將對應的高速快取中的快取行設置為無效。失效隊列的引入在很大程度上緩解了存儲快取空間有限,容易阻塞的問題。

  失效隊列的引入將監聽到遠程寫事件處理失效快取行—>返回ACK確認消息這一事務,從同步、強一致性變成了非同步、最終一致性,提高了遠程寫事件的處理效率。

記憶體屏障(Memory Barrier)

  存儲快取和失效隊列的引入在提升MESI協議實現的性能同時,也帶來了一些問題。由於MESI的高速快取一致性是建立在強一致性的匯流排串列事務上的,而存儲快取和失效隊列將事務的強一致性弱化為了最終一致性,使得在一些臨界點上全局的高速快取中的數據並不是完全一致的。

  對於一般的快取數據,基於非同步最終一致的快取間數據同步不是大問題。但對於並發程式,多核高速快取間短暫的不一致將會影響共享數據的可見性,使得並發程式的正確性無法得到可靠保證,這是十分致命的。但CPU在執行指令時,缺失了太多的上下文資訊,無法識別出快取中的記憶體數據是否是並發程式的共享變數,是否需要捨棄性能進行強一致性的同步。

  CPU的設計者提供了記憶體屏障機制將對共享變數讀寫的高速快取的強一致性控制權交給了程式的編寫者或者編譯器。

  記憶體屏障分為讀屏障寫屏障兩種,記憶體屏障以機器指令的形式進行工作。

寫屏障

  寫屏障用於保證高速快取間寫事務的強一致性。當CPU執行寫屏障指令時,必須強制等待存儲快取中的寫事務全部處理完再繼續執行後面的指令。相當於將存儲快取中非同步處理的本地寫事務做了強一致的同步。

  寫屏障指令執行完後,當前核心位於寫屏障執行前的本地寫事務全部處理完畢,其它的核心都已經接收到了當前所有的遠程寫事件的寫無效通知。

讀屏障

  讀屏障用於保證高速快取間讀事務的強一致性。當CPU執行讀屏障指令時,必須先將當前處於失效隊列中的寫無效事務全部處理完,再繼續的執行讀屏障後面的指令。相當於將非同步隊列中非同步處理的遠程寫事務做了強一致的同步。 

  讀屏障指令執行完後,當前核心位於讀屏障執行前的遠程寫無效事務全部處理完畢,對於讀屏障之後的共享數據讀取會得到最新的值。 

  在進行並發程式的開發時,針對關鍵的任務間共享變數的讀寫需要使用記憶體屏障保證其在多核間高速快取的一致性。在對共享變數的寫入指令後,加入寫屏障,令新的數據立即對其它核心可見;在對共享變數的讀取指令前,加入讀屏障,令其能獲取最新的共享變數值。

  通過在指令中的適當位置加入讀/寫記憶體屏障,雖然一定程度上降低了效率,但保證了並發程式在多核高速快取條件下對於共享變數的可見性,是一個很好的折中解決方案。

五、總結

  由於最近在學習有關硬體和作業系統相關的知識,在看到高速快取相關的內容時,便想把一直以來都一知半解的MESI協議弄懂。通過廣泛的閱讀有關部落格和書籍等資料,理解並整理後寫下了這篇部落格,希望能幫到對MESI協議等相關內容感興趣的人。

  MESI協議和記憶體屏障的知識,在其基礎之上有高級語言中c、java的volatile關鍵字的工作原理,在其下有多核並行處理器、高速快取、匯流排等硬體電路工作原理等相關的內容。在學習的過程中,一方面使我更好的理解了更上層的知識,另一方面黑盒子下還有黑盒子,令我感嘆吾生也有涯,而知也無涯。但在學習的過程中,滿足了對底層工作機制的好奇心,有著理解通透之後的快樂,還是挺有意思的。

  本篇部落格還存在很多不足之處,請多多指教。

主要參考書籍與部落格:  

《並行電腦體系結構》 

《微型電腦硬體技術及應用基礎 微機原理》 鄒逢興 

//www.cnblogs.com/hello-shf/p/12091591.html

//cloud.tencent.com/developer/article/1152642

//www.cnblogs.com/yanlong300/p/8986041.html

//blog.csdn.net/u013546788/article/details/105829283

//www.jianshu.com/p/0e036fa7af2a

//blog.csdn.net/weixin_44936828/article/details/89430358

//www.wowotech.net/kernel_synchronization/memory-barrier.html