妙不可言的虛擬存儲器

拓展:

程序的裝入和連接---http://blog.csdn.net/hguisu/article/details/5713099

 

寫在前面的

閱讀這篇文章須要計算機組成原理的基礎. 在這裏外鏈上一篇文章《關於讀書的流水帳》,有讀書感覺。虛擬存儲器的核心思想很獨到,在看了前一篇文章中提到的書中才領略到了它的魅力,硬件的東西比較多,可是也絕對能夠提升你的軟件功力,並且毫無疑問。這篇文章算是讀書筆記。html

PS:發現文中有不少的英文簡寫,爲了方便閱讀在這裏總結一下。算法

------------------------------------------------------------------------ 
中文 | 英文,英文簡寫   
------------------------------------------------------------------------數組

物理地址 | Physical Address,PA緩存

------------------------------------------------------------------------ dom

物理尋址 | Physical Addressing
------------------------------------------------------------------------ 
虛擬地址 | Virtual Addressing,VA
------------------------------------------------------------------------ 
虛擬存儲器 | Virtual Memory
------------------------------------------------------------------------ 
物理頁 | Physical Page,PP
------------------------------------------------------------------------ 
虛擬頁 | Virtual Page,VP
------------------------------------------------------------------------ 
隨機訪問存儲器 | Random Access Memory  //物理存儲器,內存
------------------------------------------------------------------------ 
頁 | Page Table,PT
------------------------------------------------------------------------ 函數

頁表條目 | Page Table Entry,PTE
------------------------------------------------------------------------ 
虛擬地址 | Virtual Addressing,VA 
------------------------------------------------------------------------ 
  性能

物理地址和虛擬地址

把主存當作是由連續字節單元組成的大數組,而且用物理地址(PA)來標識每一個數組的單元。CPU須要加載存儲器中一個字都時候,就指定這個字的物理地址的首地址,從而將存儲器中的數據返回給CPU,經過物理地址來訪問存儲器的方式就是物理尋址。因此很直觀,物理尋址方便不少,然而對於系統來講,直接物理尋址對存儲器的管理很不合理。 
image
因此有了虛擬地址(VA),經過虛擬地址訪問存儲器的方式就叫作虛擬尋址,其實這種說法不是很恰當,由於虛擬地址最終仍是會被翻譯(這個翻譯由硬件和系統協同完成的)成物理地址,從而訪問存儲器。另外,虛擬地址和物理地址是一一對應的,頁就是全相聯的。 
imageui

能夠看到,最終訪問內存的仍是物理地址(PA)。lua

 

注意啦,虛擬存儲器

image

虛擬存儲器,是由N個字節組成的,它存在於磁盤上(注意,是磁盤上,不是存儲器內存上)。另外物理存儲器和虛擬存儲器都是用頁來做爲磁盤和內存的傳輸單元。可是CPU是從內存(或者是cache)上取數據啊,而虛擬存儲器是存在在磁盤上,所以虛擬存儲器必須清楚它的哪些頁是已分配(裏面的數據是有效的)的,哪些是緩存在內存中(將數據從磁盤中拷貝到CPU能較高速訪問物理存儲器)的,哪些是已分配可是未被緩存到內存中的(數據是有效的且暫時只存在磁盤中,當須要的時候再緩衝)。spa

 

啊哈,神奇的頁表

虛擬存儲器如何知道它每一個頁的分配狀況呢?頁表(PT)從而誕生了,每個虛擬存儲器都有它本身獨有的頁表,頁表爲虛擬地址和物理地址的全相聯提供了可能。 
image 

由於有頁表的存在,因此沒有必要把虛擬存儲器(再聲明,是存在在磁盤上的)的因此頁都緩存在內存當中,即使CPU訪問該虛擬存儲器的頁不存在在內存當中,那麼系統會經過查表,把須要的頁從磁盤當中拷貝到內存當中,這裏就涉及了頁面調度的複雜算法了,並且這種算法不是單一的,這裏只簡單作個介紹。

 

有了頁表,CPU也不放心

頁命中的狀況,若是虛擬頁已經緩存到了物理存儲器那麼好辦,直接從物理存儲器中直接讀取數據就行了。 
image   
仍是這張圖,來看看簡單的命中的狀況。假如CPU給出的虛擬地址,地址翻譯硬件進行查表,經過虛擬地址定位到了PTE 2(PTE就是頁表的條目,上面有註釋)的位置,發現它的有效位是1,證實裏面的數據是有效的且數據已經緩存到了DRAM當中。因此取出PTE 2中的物理存地址來訪問DRAM,能夠看到它指向了DRAM中的VP 0,目標查找成功,OVER!!

可是頁不命中(缺頁)的狀況,那就有點麻煩了。 
 image 仍是這張圖,只是修改了一下,CPU給出的虛擬地址指向了還沒有緩衝的地址。地址翻譯硬件發現PTE 5中數據是有效的,但它並無從磁盤中緩存到DRAM中。地址翻譯硬件發現某個CPU須要的虛擬頁沒有緩存到DRAM中,就會觸發一個缺頁的異常,那麼對應的缺頁異常處理程序就會啓動。首先會選擇已緩存到DRAM的一個犧牲頁,把它拷貝會虛擬存儲器的某個位置,再將命中的虛擬頁緩存到DRAM當中。 
這時候,異常處理過程返回,從新返回到致使缺頁異常的指令,從新執行,目標命中,OVER!!另外,常常缺頁會下降程序執行的效率,不命中的處罰仍是存在的。

 

對於缺頁,是什麼解決了CPU的煩惱 

這時候有個疑問了,CPU給出的虛擬地址常常不命中,即便有頁面的調度,也會大大下降程序執行的效率。還好,有局部性存在。局部性包括時間局部性和空間局部性。 

時間局部性就是程序的數據可以被重複或者屢次引用或者被CPU讀取。空間局部性就是CPU要執行的指令或者引用的數據在一段存儲空間內。所以局部性可以在必定的程度上下降不命中的可能性。

 

進程離不開虛擬存儲器

在這裏不得不扯上進程這東西。操做系統爲每一個進程都分配了一個頁表,也就是說每一個一個進程都有個虛擬存儲器,獨立的虛擬地址空間。 
image  

因此能夠看到,每一個進程都有一張頁表,因此同一個進程的存儲空間在虛擬存儲器中能夠是不連續的,由於虛擬存儲器和頁表映射加上缺頁緩存的機制讓進程「擁有」一個「連續」的空間提供了可能,可實際上,是頗有多是不連續的。CPU提取數據的時候,都會先給出的是虛擬地址,不管頁命中仍是不命中,最後由地址翻譯硬件翻譯出來的物理地址都不會有錯。

在剛開始學c語言的時候常常用到函數scanf和printf等等一些函數,他們在本身進程中有一個虛擬地址與之對應,這樣看起來好像每一個進程內scanf和printf是分家的,實際上,因爲虛擬地址的映射,每一個進程中的這些庫函數地址都映射到了物理地址的同一個位置,這就節省了不少的空間,從而又不影響進程的獨立性。不得不本身親手畫一張在深刻理解計算機系統一書中的一個叫作「進程的虛擬地址空間」圖,很是經典。 
image

對於32位的系統,進程的虛擬地址空間有4G(其中包括了內核的和進程自己的),那難道4G都要一一映射到虛擬存儲器中?固然不是,進程虛擬空間上有空隙的,也就是說,頁表中只記錄了有效的虛擬頁。在這裏看到了我常常從本身嘴裏蹦出來的堆棧云云,看了這裏我對堆棧有了更近一步的瞭解,疑雲頓消。

相關文章
相關標籤/搜索