ReadyBoost と FILE_FLAG_NO_BUFFERING
「PC関連備忘録」の『【Windows Vista Ultima】 インストールレポート @機能編』にて,CrystalMark 2004R2 (0.9.123.320) の HDD のスコアを ReadyBoost 有り無しで比較されています.結論としては「Random Read64K」の速度が ReadyBoost 使用時に大幅に改善するとのことでした.
おもしろそうなので手元の環境でも試してみましたが,確かに同様の傾向が見られました.
CrystalMark 2004R2 がどのように HDD へアクセスしているのか Process Monitor で調べてみたところ,概ね以下のような流れでした.
- 指定ドライブ (C) にテンポラリファイルを作成
- ファイルオープン
- 1 MB 単位で同期 Write,指定サイズ (128 MB) まで埋める
- ファイルクローズ
- FILE_FLAG_SEQUENTIAL_SCAN + FILE_FLAG_NO_BUFFERING でファイルオープン
- 1 MB 単位で同期 Read をファイル先頭から繰り返す = 1 set 目
- 1 MB 単位で同期 Read をファイル先頭から繰り返す = 2 set 目
- 1 MB 単位で同期 Read をファイル先頭から繰り返す = 3 set 目
- Sequencial Read のスコア決定
- ファイルクローズ
- FILE_FLAG_SEQUENTIAL_SCAN + FILE_FLAG_NO_BUFFERING でファイルオープン
- 1 MB 単位で同期 Write をファイル先頭から繰り返す = 1 set 目
- 1 MB 単位で同期 Write をファイル先頭から繰り返す = 2 set 目
- 1 MB 単位で同期 Write をファイル先頭から繰り返す = 3 set 目
- Sequencial Write のスコア決定
- ファイルクローズ
- FILE_FLAG_RANDOM_ACCESS + FILE_FLAG_NO_BUFFERING でファイルオープン
- 512 KB 単位で同期 Read をランダムな位置に繰り返す = 1 set 目
- 512 KB 単位で同期 Read をランダムな位置に繰り返す = 2 set 目
- 512 KB 単位で同期 Read をランダムな位置に繰り返す = 3 set 目
- Random Read 512K のスコア決定
- ファイルクローズ
- FILE_FLAG_RANDOM_ACCESS + FILE_FLAG_NO_BUFFERING でファイルオープン
- 512 KB 単位で同期 Write をランダムな位置に繰り返す = 1 set 目
- 512 KB 単位で同期 Write をランダムな位置に繰り返す = 2 set 目
- 512 KB 単位で同期 Write をランダムな位置に繰り返す = 3 set 目
- Random Write 512K のスコア決定
- ファイルクローズ
- FILE_FLAG_RANDOM_ACCESS + FILE_FLAG_NO_BUFFERING でファイルオープン
- 64 KB 単位で同期 Read をランダムな位置に繰り返す = 1 set 目
- 64 KB 単位で同期 Read をランダムな位置に繰り返す = 2 set 目
- 64 KB 単位で同期 Read をランダムな位置に繰り返す = 3 set 目
- Random Read 64K のスコア決定
- ファイルクローズ
- FILE_FLAG_RANDOM_ACCESS + FILE_FLAG_NO_BUFFERING でファイルオープン
- 64 KB 単位で同期 Write をランダムな位置に繰り返す = 1 set 目
- 64 KB 単位で同期 Write をランダムな位置に繰り返す = 2 set 目
- 64 KB 単位で同期 Write をランダムな位置に繰り返す = 3 set 目
- Random Write 64K のスコア決定
- ファイルクローズ
気付いた点としては,
- 同期 Read / Write なので,ブロッキング時間を含んだスループットになっている (レイテンシの影響を排除したベスト・スループットではない)
- FILE_FLAG_WRITE_THROUGH って要らないんだっけ?
- FILE_FLAG_NO_BUFFERING 指定時にも ReadyBoost キャッシュは有効な模様
とまあこんな感じなのですが,何はともあれ同じファイルを使い回したため,その他のキャッシュが無効化された状態でも働く ReadyBoost の効果が大きく現われたようですね.今後ディスク周りのベンチマークをとるときは注意した方が良いでしょう.
なお,通常のアプリケーションは FILE_FLAG_NO_BUFFERING を同期 R/W に使用したりしないので,ベンチマークスコアの差が通常アプリケーションにそのまま適用できるとは限らない点に注意.
最後に手元の環境でのスコアでも.ベンチマークそのものが趣旨ではないので適当に.ここしばらく PicoTurbo (GH-UFD4GTB) をメインに使ってきましたが,今回から『HEX-S1GJ』*1 もテストに加えています.表の単位は MB/sec.
おまけでちょっとだけコメント.
- ReadyBoost 使用時の 40 MB/sec という数字は,USB メモリの読み出し速度 (約 27 MB/sec 前後) に,ReadyBoost の圧縮率 (150% 前後) をかけると概ね説明がつく.
- ノート PC 用の HDD ということを割引いても素の状態の Random Read 64 KB のスコアがボロボロなのが目に付くが,これが Blocking の恐怖という奴だろう.軽く近似計算してみる.まず HDD の読み出し速度を 20 MB/sec,シークタイムを 10 msec と仮定する.64 KB の転送にかかる時間は約 3 msec となるので,1 回の ReadFile に 10 msec (シーク) + 3 msec (読み出し) の 13 msec かかることになる.ということは 1 秒間の最大読み出し回数は 1000 msec / 13 msec の約 75 回.読み出せたデータ量は 75 × 64 KB で 4.7 MB となる.つまりは 4.7 MB/sec となり,実測値の 3.95 MB/sec と比べても桁としては概ね合っている.もちろん実際にはここまで単純化はできないだろうが,何を考えるべきかのとっかかりにはなるだろう.出張にたとえるとすれば,往復 10 時間を移動にかけて 3 時間働く,というのを延々繰り返しても効率は悪いよね,という話だ.
*1:id:NyaRuRu:20061214#p1 参照のこと.通販以外無いかと思ってましたが,秋葉原の[http://www.nisshinpal.co.jp:title=ニッシンパル] で 1 GB 版と 2 GB 版を見つけたので,試しに 1 GB 版を買ってみました.