一、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關鍵字的工作原理,在其下有多核並行處理器、快取記憶體、匯流排等硬體電路工作原理等相關的內容。在學習的過程中,一方面使我更好的理解了更上層的知識,另一方面黑盒子下還有黑盒子,令我感嘆吾生也有涯,而知也無涯。但在學習的過程中,滿足了對底層工作機制的好奇心,有著理解通透之後的快樂,還是挺有意思的。
本篇部落格還存在很多不足之處,請多多指教。
主要參考書籍與部落格:
https://www.cnblogs.com/hello-shf/p/12091591.html
https://cloud.tencent.com/developer/article/1152642
https://www.cnblogs.com/yanlong300/p/8986041.html
https://blog.csdn.net/u013546788/article/details/105829283
https://www.jianshu.com/p/0e036fa7af2a
https://blog.csdn.net/weixin_44936828/article/details/89430358
http://www.wowotech.net/kernel_synchronization/memory-barrier.html