# プリフェッチと先読み
## 定義
プリフェッチ(先読み、read-ahead)は、現在のファイルI/Oオフセットと前回のオフセットを比較してシーケンシャルな読み出しワークロードを検出し、アプリケーションが要求する前にディスク読み出しを予測発行してファイルシステムキャッシュに事前ロードするファイルシステム機能である。検出がうまく機能すればアプリケーションのシーケンシャル読み出し時にキャッシュヒットが起き大幅に高速化するが、検出が誤っていると不要なI/Oが発行されてキャッシュが汚れ、ディスク・I/Oトランスポートリソースが無駄になる。Linuxはこの機能をシステムコールレベルでは「先読み」(readahead(2))と呼び、アプリケーションが明示的にキャッシュをウォームアップできる。回転ディスクでは有効だが、フラッシュドライブではそれほど効果がない。(Source: [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 8 ファイルシステム]] §8.3.4, §8.3.5)
## 動作シーケンス
1. アプリケーションがread(2)を発行しカーネルにCPUを渡す。
2. データが未キャッシュのため、ファイルシステムがディスクに読み出しを発行する。
3. 前回のオフセットと現在位置を比較し、シーケンシャルなら追加の読み出し(プリフェッチ)を発行する。
4. 第1の読み出し完了時にカーネルはデータをアプリケーションに渡す。
5. プリフェッチの読み出し完了時にデータをキャッシュにセットする。
6. 将来の同じアプリケーションによるシーケンシャル読み出しはRAM内キャッシュで即座に完了する。
(Source: [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 8 ファイルシステム]] §8.3.4)
ZFSはメタデータ・zノード(ファイルコンテンツ)・vdev(仮想デバイス)ごとに異なるタイプのプリフェッチを使い分ける「インテリジェントプリフェッチ」と、1ファイルへの複数ストリーミングリーダーを個別に追跡し交互シークによるランダムI/O化を防ぐ「マルチプリフェッチストリーム」を実装している。(Source: [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 8 ファイルシステム]] §8.4.5.5)
## 横断的知見
- 本概念に触れたソースは現時点で1件([[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 8 ファイルシステム]])のため、複数ソース突き合わせによる知見の蓄積は今後の ingest に委ねる。
## 未解決の問い
- プリフェッチ検出の具体的なアルゴリズム(何回連続のシーケンシャルアクセスで発火するか、プリフェッチ距離の決定方法)は本章では触れられていない。Linuxカーネルのソースコードレベルの詳細は別途調査が必要。
- NVMe等の低レイテンシフラッシュデバイスでプリフェッチの有効性がどこまで低下するか、定量的な比較は本章にはない。
## 関連
- [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 8 ファイルシステム]] — 本概念の原典解説(§8.3.4, §8.3.5, §8.4.5.5)。
- [[ランダムIOとシーケンシャルIO]] — プリフェッチが有効に働く前提となるシーケンシャルアクセスパターンの定義。
## 出典
- [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 8 ファイルシステム]] §8.3.4, §8.3.5, §8.4.5.5