您當前的位置:首頁 > 書法

CPU是如何訪問記憶體的?

作者:由 Peter 發表于 書法時間:2018-04-26

記憶體管理可以說是一個比較難學的模組,之所以比較難學。一是記憶體管理涉及到硬體的實現原理和軟體的複雜演算法,二是網上關於記憶體管理的解釋有太多錯誤的解釋。希望可以做個記憶體管理的系列,從硬體實現到底層

記憶體分配演算法

,再從核心分配演算法到

應用程式記憶體

劃分,一直到記憶體和硬碟如何互動等,徹底理解記憶體管理的整個脈絡框架。本節主要講解硬體原理和分頁管理。

CPU透過MMU訪問記憶體

我們先來看一張圖:

CPU是如何訪問記憶體的?

從圖中可以清晰地看出,CPU、MMU、DDR 這三部分在硬體上是如何分佈的。首先 CPU 在訪問記憶體的時候都需要透過 MMU 把虛擬地址轉化為

物理地址

,然後透過匯流排訪問記憶體。MMU 開啟後 CPU 看到的所有地址都是虛擬地址,CPU 把這個虛擬地址發給 MMU 後,MMU 會透過頁表在頁表裡查出這個虛擬地址對應的物理地址是什麼,從而去訪問外面的 DDR(記憶體條)。

所以搞懂了 MMU 如何把虛擬地址轉化為物理地址也就明白了 CPU 是如何透過 MMU 來訪問記憶體的。

MMU 是透過

頁表

把虛擬地址轉換成物理地址,頁表是一種特殊的

資料結構

,放在系統空間的頁表區存放邏輯頁與物理頁幀的對應關係,每一個程序都有一個自己的頁表。

CPU 訪問的虛擬地址可以分為:p(頁號),用來作為頁表的索引;d(頁偏移),該頁內的地址偏移。現在我們假設每一頁的大小是 4KB,而且頁表只有一級,那麼頁表長成下面這個樣子(頁表的每一行是32個 bit,前20 bit 表示頁號 p,後面12 bit 表示頁偏移 d):

CPU是如何訪問記憶體的?

CPU,虛擬地址,頁表和物理地址的關係如下圖:

CPU是如何訪問記憶體的?

頁表包含每頁所在

物理記憶體

的基地址,這些基地址與頁偏移的組合形成物理地址,就可送交

物理單元

上面我們發現,如果採用一級頁表的話,每個程序都需要1個4MB的頁表(假如虛擬地址空間為32位(即4GB)、每個頁面對映4KB以及每條頁表項佔4B,則程序需要1M個頁表項(4GB / 4KB = 1M),即頁表(每個程序都有一個頁表)佔用4MB(1M * 4B = 4MB)的

記憶體空間

)。然而對於大多數程式來說,其使用到的空間遠未達到4GB,何必去對映不可能用到的空間呢?也就是說,一級頁表覆蓋了整個4GB虛擬地址空間,但如果某個一級頁表的頁表項沒有被用到,也就不需要建立這個頁表項對應的二級頁表了,即可以在需要時才建立

二級頁表

。做個簡單的計算,假設只有20%的一級頁表項被用到了,那麼頁表佔用的記憶體空間就只有0。804MB(1K * 4B + 0。2 * 1K * 1K * 4B = 0。804MB)。除了在需要的時候建立二級頁表外,還可以透過將此頁面從磁碟調入到記憶體,只有一級頁表在記憶體中,二級頁表僅有一個在記憶體中,其餘全在磁碟中(雖然這樣效率非常低),則此時頁表佔用了8KB(1K * 4B + 1 * 1K * 4B = 8KB),對比上一步的0。804MB,佔用空間又縮小了好多倍!總而言之,採用多級頁表可以節省記憶體。

二級頁表就是將頁表再分頁。仍以之前的32位系統為例,一個

邏輯地址

被分為20位的頁碼和12位的頁偏移d。因為要對頁表進行再分頁,該頁號可分為10位的頁碼p1和10位的頁偏移p2。其中p1用來訪問外部頁表的索引,而p2是是外部頁表的頁偏移。

CPU是如何訪問記憶體的?

CPU是如何訪問記憶體的?

標簽: 頁表  記憶體  虛擬地址  MMU  CPU