2017年6月16日 星期五

淺談古代CPU:32bit與4G?(2)

32位元與4GiB的太平歲月從386問世(1985)開始,差不多有10年的時間,直到Pentium Pro問世,Pentium Pro有36條定址線,所以最大可以存取的記憶體範圍是64GiB,這下子又回到了暫存器小於定址線的老問題,更麻煩的是,當初因為8086/286「本來」暫存器就比定址小,所以對應的機制是一開始就設計好的,問題是Pentium Pro的36 bit定址是後來加上去的,如果改動原來的存取機制,前面十年來為386、486寫的眾多程式還要不要活命?所以Intel的決定是:不改動原來程式的定址方式,麻煩的事情交給作業系統搞定。

在介紹Pentium Pro對付4G問題的機制前,我想應該先解釋計算機結構和作業系統都會提到的兩個名詞:「虛擬記憶體位址」和「實體記憶體位址」。

上次提過,如果把CPU當作一個抽象的黑盒子,這個黑盒子對外的行為就只有「存取記憶體」而已,不過實際的狀況下,一顆CPU會輪流跑很多獨立的程式,這時候出現一個問題,對記憶體來說,它只知道對應送來的位址,準備好要存取的資料,但是不會分辨是哪個程式的,換句話說,整個記憶體對這些程式來說是完全一樣的,你的資料我看得到,我的資料你也可以改,這樣不太好。

所以後來有人想出一種解套的方法,簡單的說,就是在黑盒子外面再包上一層黑盒子,把裡層黑盒子放出來的記憶體位址「攔截」下來,經過另外轉換後才變成真正去存取記憶體的位址,對裡層黑盒子執行的程式來說,並不會感覺到有什麼不同,而控制外層黑盒子的程式,可以對每個裡層程式的位址做出適當的轉換,讓它們每個都覺得自己才是記憶體的唯一擁有者。

在這種機制下,每個程式自己所存取的記憶體位址,叫做「虛擬記憶體位址」,而實際上真正的記憶體位址當然就叫做「實體記憶體位址」,負責轉換這兩種位址的,是CPU裡面一個特別的單元,通常稱為Memory Management Unit,記憶體管理單元,簡稱MMU,不是每個CPU都有這種機制,舉個例子,Intel 8088/86就沒有;另外有些CPU是把MMU當作另外一種「副處理器」,要另外安裝或是當作選項;另外,控制MMU的相關程式,通常是作業系統的一部份,所以兩個名詞在作業系統教科書上也看得到。

為什麼要談這個?因為Intel在32位元系統上企圖解決4G問題時,並不是讓程式「直接」就可以定址超過4G記憶體,而是去修改MMU轉換位址的機制;換句話說,對「單一程式」來說,直接可以存取的記憶體定址空間還是只有4GBytes,但是作業系統可以讓多個程式在一個比4G大的記憶體空間上並存,所以虛擬記憶體位址還是只有4GBytes,但是實體記憶體位址擴大了。

Intel有提供兩套擴展記憶體定址的機制,一套叫「實體位址擴展 」(PAE,Physical Address Extension),另外一套叫PSE-36 (36-bit Page Size Extension),因為是淺談,所以詳細的機制就省略不提,有興趣的可以直接找維基百科或是Intel的官方文件;目前的作業系統多半支援PAE,支援PSE-36的比較少;32位元的ARM上面有類似的機制,稱作LPAE(Large Physical Address Extension)。

剛剛的MMU還有後續,回想上面提過的黑盒子,我們一直假設只有CPU會去存取記憶體,其實不一定,聽過「DMA」(Direct Memory Access)和「Bus Mastering」嗎?一般來說,CPU與I/O裝置溝通有兩類方法,一類是「CPU主動」,也就是程式主動去存取I/O裝置,就像是存取記憶體一樣;另外一類是「I/O裝置主動」,這時候I/O裝置就跟CPU一樣,可以主動存取記憶體;不過古早以前,I/O裝置在存取記憶體的時候是當作「實體記憶體定址」來做的,以前是沒有什麼問題,但是當大家引入「虛擬化」的時候就成了大問題,因為虛擬化的時候。這些I/O裝置一樣要被虛擬化,可是它們存取資料的時候就露餡了,所以後來AMD才提出IOMMU這個機制,其實也就是讓I/O裝置跟CPU裡面一樣,存取記憶體時另外有MMU轉換位址。

其實關於32bit和4G還有不少有趣的故事,不過現在大部分都進入64位元時代,只能當作考古,至於64 bit以後還會不會出現類似的狀況,我想有點難,畢竟64位元定址空間並不是32位元的兩倍,而是一個很大的天文數字,不過....誰知道呢?

所以回到一開始那個問題「 在 32 位元 CPU 中,如果單純以 CPU 做記憶體定址時,4GiB 為其極限。 」在x86上,這個敘述的確不能算錯,但是這不是因為「32位元 CPU做不到」,而是Intel和AMD不想做。

沒有留言: