這篇文章是對《深入理解計算機系統(tǒng)》第九章的一個學(xué)習(xí)總結(jié),可能一篇文章寫不下,我會分兩部分寫。
《深入理解計算機系統(tǒng)》這本書是工作室一位前輩推薦的。嗯,是本很好的底層入門的書籍。書的原名叫《Computer Systems:A Programmer’s Perspective》,感覺中文的翻譯不是很貼切。不過無所謂了。sa date開始咯?。ㄙu萌~)
我們知道,在編寫一個程序的時候,就好像這個程序在完全的單獨的使用內(nèi)存,雖然,事實不是這樣的,這是靠虛擬儲存器實現(xiàn)的。虛擬儲存器是現(xiàn)代操作系統(tǒng)對主存概念的抽象,是硬件異常、主存、磁盤文件和內(nèi)核軟件的完美交互。
虛擬儲存主要有三點主要的作用:
我之所以直接寫虛擬儲存器有2個原因。第一點,虛擬儲存器在我看來是最重要的一個概念,對于二進制安全,我也認為這個概念及其重要(也可能我搞錯了,我還只是個菜雞^^)。第二點,我昨天剛剛看完這個。
物理和虛擬尋址
物理地址(Physical Address,PA)這個概念是不需要過多的解釋,就是指物理內(nèi)存的地址。虛擬地址(Virtual Address,VA)直觀的講,c語言里的指針?biāo)玫木褪翘摂M地址。虛擬地址就是一種儲存器的抽象。使用物理地址的尋址方式是物理尋址,使用虛擬地址的尋址方式的成為虛擬尋址。
地址空間
地址空間就是一個地址的數(shù)組,有虛擬地址空間和物理地址空間
虛擬儲存器作為緩存的工具
概念上來說,虛擬儲存器被組織為一個由存放在磁盤上N個連續(xù)的字節(jié)大小的單元組成的數(shù)組。每個字節(jié)都有唯一的虛擬地址。和儲存器的層次結(jié)構(gòu)的中的其他的緩存一樣,磁盤(較低層次)的數(shù)據(jù)被分割成塊,這些塊作為磁盤和主存(較高層次)之間的傳輸單元。VM系統(tǒng)將虛擬儲存器分割為稱為虛擬頁(Virtual Page,VP)的大小固定的塊。每個塊大小為P字節(jié)。物理儲存器也被分割為物理頁(Physical Page,PP)大小也是P字節(jié)。物理頁也被稱為頁幀(page frame)。
任意時刻,虛擬頁面都被分為三個不相交的子集:
未分配:VM系統(tǒng)還未分配(或者創(chuàng)建)的頁,不占用任何磁盤空間。
緩存的:當(dāng)前已緩存在物理儲存器中的已分配的頁
未緩存的:沒有緩存在物理儲存器中的已分配的頁。
我們用DRAM緩存來表示主存中對虛擬儲存器的緩存。我們知道DRAM比磁盤塊了1000000多倍(關(guān)于SRAM和DRAM的介紹,自行谷歌,不過我最近也會寫一個關(guān)于這個的簡單介紹),而SRAM比DRAM快了將盡10倍。所以,任何對DRAM的不命中都會招致很大的性能懲罰,是一巨大的開銷。因此,虛擬頁往往很大,典型是在4KB~2MB之間。由于大的不命中懲罰,DRAM也是全相連的。同時操作系統(tǒng)也對DRAM使用了精密的替換策略。
每個進程都有一個由頁表項(PTE)組成的頁表。先簡化一下概念。我把頁表項認為成一個有效位和其他的地址位組成的。當(dāng)有效位是0的時候表示這一頁還不在主存中,他可能還沒創(chuàng)建或者沒有在內(nèi)存中,后面的地址位表示頁在磁盤的位置。當(dāng)有效位是1的時候,表示這一頁在內(nèi)存中,地址位表示這一頁的起始位置。當(dāng)cpu引用一個不在內(nèi)存中的頁的時候,會引發(fā)一個缺頁異常。內(nèi)核的缺頁處理程序?qū)M行處理。在磁盤和儲存器間的頁傳送活動叫交換(swapping)或者頁面調(diào)度(paging)。頁從磁盤換入(頁面調(diào)入)DRAM和從DRAM換出(頁面調(diào)出)磁盤。
此時,程序的局部性的作用就再次體現(xiàn)出來了。一個局部性差的程序,可能導(dǎo)致其工作集超過內(nèi)存的大小,導(dǎo)致頁面不斷換入換出,此時程序慢的像爬一樣,這種狀況叫做程序的顛簸(thrashing)
再談虛擬儲存器的作用
作為儲存器的管理工具
系統(tǒng)通過頁表把每月頁映射到內(nèi)存的頁上,簡化了鏈接、加載、共享以及儲存器的分配
作為儲存器的保護工具
任何現(xiàn)代計算機系統(tǒng)都必須為操作系統(tǒng)提供手段來控制對儲存器的訪問。每次地址的翻譯都需要PTE ,PTE上有各種控制位,如SUP位:為1時,只能內(nèi)核模式訪問。用戶態(tài)程序只能訪問SUP為0的頁。READ位和WRITE位控制對頁的讀和寫權(quán)限。如果一條指令違反了許可條件,cpu就觸發(fā)一個一般保護錯誤,將控制移交給內(nèi)核異常處理程序。Unix外殼一般講這種異常報告為段錯誤(segmentation fault)。
地址翻譯
先弄一個表
CPU芯片上有一個叫做儲存器管理單元(memory management unit,MMU)的硬件實時的翻譯虛擬地址為物理地址。一個虛擬地址由2部分組成,p位的虛擬頁面偏移(virtual page offset,VPO)和一個(n-p)位的虛擬頁號(virtual page number,VPN)組成。MMU根據(jù)VPN來選擇PTE。例如VPN0選擇PTE0.物理地址也是2部分組成的,物理頁面偏移(physical page offset,PPO)和VPO的位數(shù)是一樣的,物理頁號(physical page number,PPN)。CPU中還有一個控制寄存器,叫作頁表基址寄存器(page table base register,PTBR),這個寄存器儲存著頁表的地址,是一個進程的上下文。
頁面命中時:
頁面未命中時:
結(jié)合高速緩存的虛擬儲存器
現(xiàn)代操作系統(tǒng)使用了物理尋址來訪問高速緩存,關(guān)于是使用虛擬地址還是物理地址來訪問時存在爭論的。這是一種折中的方案(關(guān)于具體的書中沒有介紹)。
使用TLB加速地址訪問
現(xiàn)代計算機系統(tǒng)中在MMU中包含了一個緩存PTE的高速緩存翻譯后備緩沖器(translation lookaside buffer,TLB),以加速翻譯。
多級頁表
目前為止,我們只使用一級頁表,我們假設(shè)一個32位的地址空間,4KB的頁面和一個4字節(jié)的PTE,那么即使應(yīng)用所引用的只是虛擬地址的很小一部分,也需要4MB的頁表駐留在內(nèi)存,這是一種嚴重的浪費。對于64位系統(tǒng),這將變的更復(fù)雜。
我們使用層次的頁表。我們使用一個二級頁表作為例子來解釋。
一級頁表負責(zé)映射虛擬空間中的一個4MB的片(chunk),每個片都是由1024個連續(xù)的頁組成的。假設(shè)4GB地址空間1024個片就可以覆蓋完整個地址空間。如果片i沒被分配,那么這片i就為空。
二級頁表每個PTE都負責(zé)映射一個4KB的虛擬儲存器頁面。
這樣有2個好處:
下圖描述了一個k級頁表結(jié)構(gòu)
inter core i7/linux儲存器系統(tǒng)
Core i7是基于Nehalem微體系結(jié)構(gòu)的。雖然Nehalem設(shè)計允許完全的64位虛擬地址和物理地址空間。而現(xiàn)在其實現(xiàn)支持48位(256TB)虛擬地址空間和52位(4PB)物理地址空間,還有一個兼容模式,支持32位(4GB)虛擬和物理地址空間。
下圖是Core i7的重要組成部分,頁的大小被配置為4KB和4MB。linux使用4KB的頁
Core i7的地址翻譯
下圖總結(jié)翻譯過程和第一、二、三級頁表結(jié)構(gòu),Core i7采用4級頁表。雖然Core i7允許頁表換進換出,但與已分配內(nèi)存頁面相關(guān)的頁表都是在儲存器中的。CR3控制寄存器指向一級頁表的起始位置,是進程上下文的一部分。物理也是4KB對齊的。
第四級頁表
linux虛擬儲存系統(tǒng)
下圖是一個linux的虛擬儲存器
linux將儲存器組織成一些區(qū)域(也叫段)的集合。例如,代碼段,數(shù)據(jù)段,用戶棧等就分屬不同的區(qū)域(area)。不存在不屬于某個區(qū)域的虛擬頁,并且不能被進程引用。區(qū)域概念很重要,因為它允許虛擬地址空間有間隙。內(nèi)核不需要記錄那些不存在的虛擬頁,而這些不存在的虛擬頁也不占用任何資源。
下圖強調(diào)了一個記錄一個進程中虛擬存儲器的內(nèi)核數(shù)據(jù)結(jié)構(gòu)。內(nèi)核為系統(tǒng)中每個進程維護一個單獨的任務(wù)結(jié)構(gòu)(源代碼中的task_struct)。任務(wù)結(jié)構(gòu)中包含或者指向內(nèi)核運行該進程所需要的全部信息(PID,指向用戶棧的指針、可執(zhí)行目標(biāo)文件的名字以及程序計數(shù)器等)。
task_struct中有個條目指向mm_struct,它描述了儲存器當(dāng)前的狀態(tài)。我們感興趣的是pgd和mmap,pgd指向第一級頁表的基址,而mmap指向一個vm_area_structs(區(qū)域結(jié)構(gòu))的鏈表,每個vm_area_structs都描述了當(dāng)前虛擬地址空間的一個區(qū)域。
linux缺頁異常處理程序
處理程序執(zhí)行下面的步驟
儲存器映射
linux下虛擬儲存區(qū)域可以映射到2種類型對象中的一種:
無論何種情況,一旦一個虛擬頁面被初始化,它就在一個內(nèi)核維護的專門的交換文件(swap file)間換出換進。交換文件也叫交換區(qū)(swap area)。任何時候,交換區(qū)都限制著當(dāng)前運行著的進程能夠分配的虛擬頁面總數(shù)。
共享對象
共享對象對所有相關(guān)進程都可見的,同時對其的修改也會反映到磁盤上的原始對象上。
私有對象
私有對象是私有的,對其進行的寫是不會反映到原始的磁盤對象上的,私有對象使用了寫時拷貝的技術(shù)
好了,今天就到這里。最后雪雪亂入!
聯(lián)系客服