檔案系統與儲存

預讀(read-ahead)

當你從頭開始讀一個檔案並持續往下讀,電腦可以做一個不錯的猜測:你大概也會想要下一段。與其等你逐塊去要、再一次一趟慢磁碟之旅地取,核心會預讀——它在你請求之前就把檔案接下來的部分取進頁面快取,所以等你要的時候,資料已在 RAM 裡。那種對你尚未要求之檔案資料的投機性預先擷取,就是預讀。

核心觀察你的存取模式。如果你的讀取看起來是循序的——偏移 0、再 4 KiB、再 8 KiB——它便斷定你正在串流走過這個檔案,並開始在你目前位置之前拉進更大的視窗,隨著循序連續延續而擴大預讀視窗(常至一個上限,如 128 KiB)。它也把這與你的處理重疊:當你在咀嚼已送達的位元組時,下一個視窗正在背景被擷取,把磁碟延遲藏在有用的工作之後。若你的讀取反而隨機跳躍,核心會偵測到預測沒有划算、便縮小或停用預讀,以免在你不會碰的頁上浪費頻寬與快取。你也可以用 posix_fadvise()(POSIX_FADV_SEQUENTIAL 積極預讀、POSIX_FADV_RANDOM 關掉它)或對映射用 madvise() 給出明確的提示。

為何重要:預讀是「串流一個大檔案、複製它、或循序掃描一個資料庫」之所以能達到近乎磁碟頻寬的吞吐、而非以每區塊一個請求的延遲爬行的一大原因。誠實的注意事項:它是一個啟發法、可能猜錯——對一個真正隨機的工作負載積極預讀,會用你從不使用的頁汙染快取、並浪費 I/O 頻寬,這正是為何對隨機存取告訴核心 POSIX_FADV_RANDOM 反而可能加快速度。

偵測到循序讀取: 應用要區塊 0..1 核心悄悄把 0..31 取進快取 應用要區塊 2 -> 已快取、瞬時;視窗往前擴大 posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL); // 提示:積極預讀

在循序模式下,核心在需求之前就擷取未來的區塊,藏住磁碟延遲。

預讀是一個猜測。在隨機存取的工作負載上,它浪費頻寬、並用你從不讀的頁汙染頁面快取;告知 POSIX_FADV_RANDOM(或用 O_DIRECT 自行管理快取)反而可能加快這類工作負載,而非拖慢它。

又稱
readaheadprefetchingsequential prefetch預讀預先讀取