操作系統的作業:內存管理。TLB、LRU、clock

實驗內容:

1、閱讀代碼回答問題

(1) 當前系統下,內存大小Mainmemory是多少?

PageSize=128,  NumPhysPages=128,   Mainmemory=128*128=2^7*2^7=2^14;  內存大小是4KB

(2) 理解從空間分配,加載代碼數據,取指執行的流程

空間分配:調用AddrSpace的構造函數,先爲該進程分配頁表,然後使用for循環建立虛擬內存和物理內存之間的對應關係。

加載代碼數據:這部分功能由AddrSpace類中的load()函數實現。在這個函數中,打開了用戶文件,讀文件頭中的信息,計算所需要的內存大小,再調用divRoundUP()函數計算所需要的頁的個數。然後根據文件頭中的信息,如果有代碼段,寫入kernel內核中的主存中,數據段也是同樣的道理。

取指執行:初始化CPU寄存器,使得它指向需要指向的第一條指令。由於load()加載的數據是虛擬地址,寄存器讀取的也是虛擬地址,所以正式執行前需要進行轉換。初始化寄存器是AddrSpace()類中的InitRegister()方法。還需要RestoreState()函數將進程中的頁表拷貝到CPU中去維護。最後調用machine中的Run()方法,使用OneInstruction函數模擬一次取指令和執行該指令的操作。

(3) PageTable表中,虛擬地址和物理地址的對應關係如何?Translate函數如何工作

① Translate()函數有4個參數:

l virtAddr:用戶程序的邏輯地址;

l physAddr:轉換後的實際地址;

l size:數據類型的大小;

l writing:讀/寫內存標誌

   

② 判斷用戶的邏輯地址是否對齊:

l 如果size是2,virtAddr必須是2的倍數;

l 如果size是4,virtAddr必須是4的倍數。

l 沒有對齊則返回AddressErrorException。

 

③  計算出虛擬地址所在頁號vpn以及所在頁面的偏移量

 

 

 

 

④   採用不同的轉換方法做不同的處理:

l 如果採用的是線性轉換表:當vpn>=pageTableSize時,虛擬頁數過大,返回AddressErrorException;如果頁表中顯示該頁無效,返回PageFaultException;一切正常得到相應的頁表表項。

l 如果採用的是TLB轉換表:如果查找到了,得到相應的頁表表項;如果沒有查找到,返回PageFaultException

⑤   如果得到的頁表表項是隻讀,但是設置的是writing,返回ReadOnlyException

⑥ 如果物理地址大於實際內存物理地址,返回BusErrorException

⑦ 設置表項正在使用標誌,如果writing標誌設置,設置表項中的dirty標誌

⑧ 然後在頁表中查找它們所在的物理頁框號,計算物理地址。

 

返回NoException。

 

 

(4) 什麼情況下會產生PageFault的exception, 是否有對應處理函數?

在Translate()函數中,採用線性轉化表時,如果查找的頁是無效的,返回PageFaultException;採用TLB表,如果沒有查到,返回PageFaultException。Translate()函數在ReadMem()函數中被調用,因而PageFaultException被返回到ReadMem()函數中進行判斷,並被傳入到RaiseException()函數中,這個函數會調用ExceptionHandler()函數,由它對傳入的異常進行處理。

在這個函數 中,由switch語句判斷傳入的是異常還是系統調用,如果是系統調用再採用一個switch-case語句判斷是何種系統調用;如果是異常直接打印出錯信息。需要說明的是,在處理完PageFaultException之後,不需要將PC+4。因爲處理完異常後,返回的最終位置是OneInStruction函數的取指階段,取指失敗後,OneInstruction會退出,再用相同PC取指令。這個時候就可以命中了。

 

2. 設計LRU策略下的TLB

(1) 在本次實驗中爲了減少代碼量,設定TLBPageTable的關係如下所述:

TLB在系統中唯一,所有線程可用;PageTable爲每個進程一個;

系統尚未實現真正意義上的虛擬內存管理,系統僅運行一個用戶線程;

系統同時有TLBPageTableTLB視爲對PageTable中部分代碼的高速緩存;

系統開始之初,TLB爲空,PageTable NachOS代碼完成原來的初始化;

系統取指時,地址的翻譯由函數Translate()進行,這時從TLB中的頁表項查找物理地址和虛擬地址的對應關係;

如果不命中,則產生PageFault異常,轉移到異常處理函數進行處理;

該處理函數需要自己寫,完成從PageTable加載對應頁表項到TLB

線程切換時,TLB需要清空;

加載到TLB之後,需要回到中斷產生的地方,繼續執行

(2) machine.h .cc中完成TLB的定義和初始化,修改數據結構增加時間記錄變量

(3) 完成異常處理函數調用,以LRU方式進行TLB替換;注意必要時同步被替換項回到PageTable//加分clock算法

(4) 時間信息可以來自stats下的totalTicks(溢出情況不考慮,該值爲int,有一定隱患);加入必要的信息,顯示缺頁異常發生,和TLB哪個頁表項在進行替換,替換成哪個頁表項

(5) 運行程序觀測是否正常?如果不正常請跟蹤代碼,發現缺頁異常處理返回後程序沒有重新正常運行;

(6) 修改WriteMemReadMem,在缺頁異常處理返回後重新調用Translate()函數

答案:

LRU運行截圖:

修改的代碼:

 

源碼中已經給出了TLB的實現,在machine.h中增加一個宏定義,使得nachos產生一個TLB

需要注意的是,在Translate.cc中的Translate()函數中有一個判斷,意思是TLBpage table不能同時存在,需要將它註釋掉。

Translate.h中,在TranslateEntry中增加一個屬性lastUseTime

 

Exception.cc中。判斷TLB缺頁,拋出的exceptionTranslateFaultException,在switch函數中進行判斷,並且判斷是不是TLB缺失。調用LRU算法。

machine.h,實現TLB的構造,對lastUseTime進行賦值

 

machine.cc中實現MyHandleTLB()函數:

Translate.cc中,修改WtriteMem()函數,發生exception時,先判斷是不是PageFaultException,如果是,調用了RaiseException()函數後,缺頁已經解決,再次調用Translate()函數。

ReadMem函數中修改方法相同

2. (選做)以CLOCK方式,僅使用use標誌位

運行截圖:

修改代碼:

Translate.h中,在TranslateEntry中增加一個屬性useTag

Translate.cc中的Translate()函數以及ReadMem()WriteMem()函數依然和LRU函數中的一樣,不需要修改。

Exception.cc中。判斷TLB缺頁,調用clock算法

Machine.h中,在machine類中增加clock算法處理TLB缺頁的函數聲明:MyClockTLB(int addr);

Machine.cc中,實現這個函數。

現在文件頭上增加一個全局變量cursor,這個是時鐘算法中的指針。

TLB構造函數中,對useTag賦值爲0

 

下面是對MyClockTLB(int addr)函數的實現

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章