虛擬記憶體與需求分頁

頁錯誤服務(page-fault service)

想像一位圖書館員在你要一本不在開架上的書時的處理流程。她查目錄,確認這本書真的存在並找出它存放在哪裡。她走去閉架書庫(或向館外調借)。如果歸還推車滿了,她清出一個位置,也許把一本好一陣子沒人碰的書放回架上。她去把你要的書取來、記錄它現在已上架,最後告訴你可以從剛才停下的地方繼續讀。頁錯誤服務就是作業系統執行這一整套完全相同的步驟,來滿足一個缺失的頁。

具體來說,當一次分頁錯誤陷入作業系統時,它會執行一段固定的步驟序列。首先,它檢查一張內部表,判斷這次參考究竟合不合法;若位址在行程空間之外,就終止該行程。若參考合法、只是該頁不在常駐,它就從空閒頁框清單中找出一個空閒頁框。若沒有空閒頁框,它必須挑選一個犧牲頁趕走,而若那個犧牲頁曾被修改過,就要先把它寫回後備儲存(page-out)。接著它排定一次磁碟讀取,把想要的頁從後備儲存帶進選定的頁框;在磁碟運作的同時,CPU 可以執行其他行程。當讀取完成,作業系統更新該行程的分頁表,把該頁標記為有效並指向新頁框,把行程放回就緒佇列,並安排重新啟動造成錯誤的那道指令,使這次存取現在得以成功。

為什麼重要:這段序列就是需求分頁的全部機制,而它幾乎所有的成本都在中間那次磁碟讀取。CPU 的工作——陷入、檢查表、更新項目——很快;相較之下磁碟存取慢如冰河。這就是為什麼服務一次錯誤的成本以毫秒計,而普通的記憶體存取以數十奈秒計。誠實的推論是:每一次可避免的錯誤都極其昂貴,這正是為什麼整個設計如此倚重區域性(讓錯誤罕見)以及聰明的分頁置換(讓挑出的犧牲者是不太可能很快又被需要的那一頁)。

一次錯誤的步驟:(1) 陷入作業系統;(2) 檢查參考合法;(3) 找出空閒頁框,或趕走一個犧牲頁(若它是髒的就先寫回);(4) 對該頁框發出磁碟讀取;(5) 完成後,把分頁表項目設為有效;(6) 重新啟動造成錯誤的那道指令。

中間那次磁碟讀取主導了整個服務時間。

一次錯誤可能花掉兩次磁碟傳輸,而非一次:若選中的犧牲頁框存放著一個被修改過(髒)的頁,作業系統必須先把該頁寫出,才能把想要的頁讀進來。盡量選擇乾淨的犧牲頁可以省下一半成本——這是修改位元(dirty bit)存在的原因之一。

又稱
page-fault handler頁錯誤服務常式缺頁處理