預先分頁(prepaging)
想像一位服務生,他不是每次你點下一道菜就走去廚房,而是注意到你總是依序點湯、再點主菜、再點甜點——於是他在你快吃完當前這道之前,就把下一道端出來。他猜你會想要什麼,並提前去取,所以你很少等待。預先分頁就是作業系統扮演這位會預判的服務生:在頁被參考之前就把它帶進記憶體,猜測它們很快會被需要,以避免使用當下因錯誤而停頓。
具體來說,預先分頁預先把一組頁載入頁框,而非等待每一頁都被一次錯誤所要求。經典的動機是純需求分頁下行程的啟動,此時最初的參考會引發一陣錯誤;預先分頁一次帶進一批可能需要的頁,使那許多次錯誤收攏成較少、較大的磁碟讀取。同樣的想法也適用於恢復一個被換出的行程(把它先前整個工作集一起帶回來),或當空間區域性暗示觸碰一頁就代表鄰近的頁也會被需要時(預讀)。這個賭注立基於預測:唯有它所猜的頁大多真的被用到,預先分頁才划算。
為什麼重要:預先分頁以確定性換取速度。需求分頁絕不載入用不到的頁,但每次第一次都要付一次錯誤;預先分頁靠批次處理攤平啟動成本,而少數幾次大型的循序磁碟讀取,遠比許多次零散的單頁讀取有效率。誠實的隱憂是這場賭博:若預測的頁猜錯了,預先分頁就把磁碟頻寬與頁框浪費在沒被碰過的頁上,還可能為了騰位置而趕走有用的頁。所以它在存取可預測時(循序掃描、還原已知的工作集)有幫助,在不可預測時則有害。它是純需求分頁實務上的互補,在不放棄延遲載入作為預設的前提下,緩和啟動時的錯誤風暴。
當一個曾被換出的行程再次變為就緒,作業系統不是一次一頁地把它的工作集逐頁分頁回來,而是把那些頁全部一批預先分頁進來——用一次大型磁碟讀取取代數十次小型錯誤。
把預測的頁批次處理,能把許多次小錯誤變成一次有效率的讀取。
唯有預測大致正確,預先分頁才划算。帶進來卻從未使用的頁,浪費了磁碟 I/O 並佔用了本可存放所需頁的頁框——因此在不可預測、隨機存取的工作負載上激進地預先分頁,可能弊大於利。