書籍紹介: Advanced Windows 第5版

Windows VIA C/C++ , Fifth Edition - NyaRuRuの日記』をお伝えしてから10ヶ月,日本語翻訳版がいよいよ発売です.日本だと『Advanced Windows』が7年ぶりに改訂と言った方が伝わりやすそうですな.

Advanced Windows 第5版 上 (マイクロソフト公式解説書)

Advanced Windows 第5版 上 (マイクロソフト公式解説書)


Advanced Windows 第5版 下 (マイクロソフト公式解説書)

Advanced Windows 第5版 下 (マイクロソフト公式解説書)


原書持ってますが,例によって私は引用目的買いで.


個人的にお気に入りの Vista 新機能のうち,同書で解説されているものを紹介しておきます.

つまりここに挙げたような内容についての記事を書くときに引用チャンスと.というわけでまあ買いで.
Transactional NTFS の解説が入っていないのはちょっと悲しいところですかね.でもまあ買いで.

あわせて予約したい (原書)

『インサイド Microsoft Windows 第5版』(恐らく上下巻) になるであろう本の原書 (になるであろうはずのもの) にして,出版延期を繰り返した結果 Windows 7 より先に出るかが気になる今日この頃のような,そんな Mark Russinovich 大先生の至高の一冊 (になるはずのもの).

Windows® Internals, Fifth Edition (PRO-Developer)

Windows® Internals, Fifth Edition (PRO-Developer)

記事紹介: Inside Vista SP1 File Copy Improvements (1)

ZDNet の翻訳記事より.『「Vista SP1」対「XP SP2」ふたたび--Windowsベンチマーク対決第2弾

最初のベンチマークテストに寄せられた主な批判の中に、ファイルコピーの際、見えない部分でVista SP1とXP SP2の動きが違うという事実を、私が見過ごしているというものがあった。この違いはハードディスクへの書き込み時のキャッシュに由来するもので、XPはファイルをキャッシュするのに対し、Vistaの標準設定では書き込み時のキャッシュは無効になっている。加えて、ファイル転送のプログレスバーの仕様が異なり、XPとVistaでは挙動が異なることが、事態をさらに複雑にしている。Vistaではキャッシュがディスクにコミットされた時点でファイルコピーの経過を示すダイアログボックスが消えるが、XPではキャッシュのコミットが待ち状態であってもダイアログが消える。つまり、XPは速く「見える」ように設定されているのだ。この点について、Mark Russinovich氏が以下に詳しく説明している。

おそらく、このアルゴリズムの最大の欠点であり、多くのVistaユーザーが不満を訴える原因の1つになっているのは、サイズが256Kバイト〜数十Mバイトの大量のファイル群を含むコピーでは、体感上のコピー性能がWindows XPよりかなり悪くなることがある点だ。XPのアルゴリズムではファイルI/Oにキャッシュを用いているため、Explorerは目的ファイルのメモリへの書き込みが終わると、コピーのダイアログボックスを消してしまう。実際にはその後もCache Managerがバックグラウンドでデータをディスクにコミットしており、その処理にはもっと時間がかかる。一方、Vistaのキャッシュを使わないアルゴリズムの場合、Explorerはそれぞれの書き込み処理が完了するまで次の処理の命令を待つことになり、最終的にはコピーするデータがすべてディスクに書き込まれるまで「コピー完了」と表示しない。また、Vistaの場合、Explorerがコピーにかかる時間の予測を始めるまで12秒待つうえ、この予測計算のアルゴリズムはコピー速度の変動に左右されやすく、両者が相まって、ユーザーはXPより時間のかかるコピーにイライラを募らせることになるわけだ。

とにかく、Russinovich氏の記述が事実なら、XPは、信頼性を犠牲にして体感上の性能をアップさせ、ファイルのコピーが高速だとわれわれに信じ込ませていたことになる。それならば、コピーのスピードはいったん横に置いておいて、問題を違う角度から見ることにしよう。大容量ファイルを転送しているときのレスポンスを検討するのだ。というわけで、ファイルコピー操作中のシステムをベンチマークテストにかけることにする。

この記事に関するブックマーク を読んでいると,「何でそんなことするの?」って話が出てました.
確かにこの ZDNet の記事だとだいぶ意味不明かも.というか何のベンチマークを取りたいのかさっぱり分かりませんでした*1
いずれにせよ,『Inside Vista SP1 File Copy Improvements』の解説記事はいつか書こうと思っていたものです.というか半分ぐらいは書けているのですで,とりあえず書けている部分だけでも置いておきますかね.というわけで以下 "Inside Vista SP1 File Copy Improvements" の副読記事みたいなもの.訳じゃなくて色々順序を変えたり補ったりしてるのでご注意を.とりあえず時間がある方はオリジナルの記事を一読されることをおすすめします.

Cached I/O V.S. Non-Cached I/O

従来のファイルコピーと Windows Vista 無印のファイルコピーの最大の対立軸は,前者が Cached I/O を使用するのに対して,後者が全面的に Non-Cached I/O への書き直しを行ったというところ.ただしオチを先に言ってしまえば Vista SP1 でやっぱり Cached I/O に回帰.「何だ結局失敗か」と言うは易し.彼らが何を学んだか見てみますかね.

Cached I/O の特徴と問題点

元記事ではまずこのあたりを重点的に解説.というわけで「インサイド Windows」のおさらい.
CreateFile でファイルを開くとき,デバイスが Cached I/O をサポートしなかったり,意図的に Cached I/O を回避しない限り,基本的に Cached I/O モードが選択される.
さて,ここで言う Cache の実体は何だろう? リングバッファや STL の queue を挟み込むパイプライン構造を想像した人は残念ながら外れ.
Cached I/O 使用時は,OS が勝手にファイルのメモリマッピングを行っていると考えると分かりやすい.
Cached I/O モードでは,ファイルの該当領域が OS によって内部的に MapViewOfFile される.そして ReadFile や WriteFile は,この内部領域との memcpy として振る舞うことになる.
ファイルから ReadFile でデータを読み取るときの何が起きる? ここで分岐.

  1. 該当領域に対応する物理ページが一切存在しない場合
    • ハードページフォルトが発生して,物理メモリに内容をコピーした上で,memcpy
  2. ワーキングセットに該当領域は存在しないが,物理ページには見つかった場合
  3. ワーキングセットに該当領域が存在した場合
    • 単なる memcpy

ディスクキャッシュがメモリマップドファイルと同じ意味で,メモリマップドファイルが一種の共有メモリであることを知っていれば,先読みキャッシュの実装も簡単に理解可能.別プロセスで同じ領域をメモリにマップして,次に読み込まれそうなページを先にフォールトさせればよい.メモリは共有されているので,これで Explorer から見てもメモリに読み込まれたことになる,と.
以下実演の引用.これは Windows XP でのファイルコピーの流れ.

The copy engine relied on the Windows Cache Manager to perform asynchronous read-ahead, which essentially reads the source file in the background while Explorer is busy writing data to a different disk or a remote system. It also relied on the Cache Manager’s write-behind mechanism to flush the copied file’s contents from memory back to disk in a timely manner so that the memory could be quickly repurposed if necessary, and so that data loss is minimized in the face of a disk or system failure. You can see the algorithm at work in this Process Monitor trace of a 256KB file being copied on Windows XP from one directory to another with filters applied to focus on the data reads and writes:

分かりやすく表にしてみる.

event Process Read range Real disk read Write range Real disk write
1 Explorer 0 ~ 64 KB
2 Explorer 0 ~ 64 KB
3 System 128 KB ~ 196 KB
4 System 196 KB ~ 256 KB
5 Explorer 0 ~ 64 KB
6 Explorer 64 ~ 128 KB
15 Explorer 64 ~ 128 KB
16 Explorer 64 ~ 128 KB
17 Explorer 128 KB ~ 196 KB
18 Explorer 64 ~ 128 KB
19 Explorer 196 KB ~ 256 KB
22 Explorer 196 KB ~ 256 KB
23 Explorer End of File
811 System 0 ~ 64 KB
1175 System 64 ~ 128 KB
1213 System 64 ~ 128 KB
1233 System 196 KB ~ 256 KB

まずイベント 1 と 2 に注目.プロセスは Explorer.Event ID 1 のものがユーザモードの読み取り要求で,Event ID 2 のものがカーネルモードに昇格して物理ディスクからの読み取り処理,と考えればこれは OK.Event ID 2 は同期 I/O で,読み取りが完了されるまでスレッドはブロックされる.
一方 Event ID 3, 4 は何かというと,これらが先ほど述べた「先読み」.System プロセスで事前にページフォルトを起こすことで,あらかじめメモリマップドファイルの中身を埋めてしまっている.当然これらの読み込みも同期 I/O で,ページ読み込みが完了するまでブロックされるんだけど,プロセスが別である Explorer はその間も別の作業を行うことができる.かくして,Explorer から見れば,「バックグラウンドで先読み」が行われているというわけ*2
続いて Event ID 6, 17, 19 に注目.Explorer からのファイル読み込みだけど,そこは既に System プロセスが読み込んだ場所,なので実際には memcpy + オーバーヘッドのコストしかかからない.先読み速度が適切だと,Explorer からのファイル読み込みは常に memcpy 程度のレイテンシで収まることになる.やったね.
書き込みは逆の流れをたどる.Explorer の書き込み先は,いきなり生ファイルというわけではなくて,まずはメモリマップされたメモリページに書き込まれる.これが例えば Event ID 5, 16, 18, 22.ちょっとしたオーバーヘッドはあるものの,ここでも基本的に Explorer からのファイル書き込みは memcpy 程度のコストになる.つまり WriteFile が成功を返して実際にディスク書き込みが行われるまではずいぶん差がありますよ,と.
じゃあ本当にディスクに書き込まれるのはいつ? というとそれが Event ID 811, 1175, 1213, 1233.ID の値から見ても分かるように,そこそこ時間が経ってるみたい.なぜって同じメモリページに何度も書き込まれる可能性ありますよ? だったらしばらく様子を見て最後の結果のみを書けば書き込みは一回で済んでいいですねと*3
こうやって見ると Cached I/O ではメモリ共有と割り込みを活用したプロセス間並列処理の一種と言えるかな.Explorer のコードを一切修正することなく,先読みや怠慢な書き出しが外部から注入できているところに注目.例えば WriteFile を全部実行し終わった Explorer は,さっさと終了してしまって構わないですよと.代償は,データを共有するためにメモリを消費するところ.その意味で,Cached I/O はメモリリソースを代償にレスポンスを稼ぐ方向とも言えますな.

Cached I/O だとなんでまずいか?

Windows XP まで,ファイルコピー (Explorer とそのバックエンドである CopyFileEx API) の実装は,Cached I/O を使ってた.そして Vista 開発時に製品開発チームは考えた.

  • 巨大なファイルをコピーするとき,Cache Manager の書き込みスレッドが間に合わないことがあるよ.
    • 最終的には,ワーキングセット以外のメモリを埋め尽くすまでキャッシュを汚染しまくるよ.

XP まではしばしばコピー読みだしの速度に変更済みページの書き出しががついていけないことがあった.そんなところに数百 MB のファイルコピーを行うと何が起きる?
いわゆる「キャッシュメモリ」が余っている限り,次々にメモリマップドファイルの書き出し先に転用されてしまう.もそもとその物理メモリは何かのデータを保持していたわけで,それが例えばメモリマップされた別のファイルであればディスクキャッシュがパージされたことになり,ページファイルと同期済みのヒープの内容であればいわゆる「ページアウト」の完成.(でも手元の XP 環境だと,遅延書き込みせいぜい 20 MB ぐらいまでっぽい.この辺り要調査)
つまり,アプリケーション最小化→しばらく放置 (ページファイルとの同期待ち) →大量のファイルコピーという単純コンボで,ページアウトされたアプリケーションの一丁上がり.
誰もファイルコピーの遅延書き込みがキャッシュを大量に汚染するかもしれないなんて考えもしないよね? でもみんなコピーダイアログのプログレスバーがぐんぐん伸びていくと気持ちいいですよ.多分それが「Think About Emotions*4
問題は他にもリモートファイルコピーにもありましたと.

  • リモートファイルシステムからファイルをコピーするとき,データが 2 回キャッシュされるよ.
    • ひとつはリモートからファイルが読み込まれるときだよ.
    • もうひとつはローカルにファイルが書き込まれるときだよ.
    • 加えて両方のファイルをメモリマップするのは CPU オーバーヘッドがあるよ.(読み書きに対応してキャッシュマネージャによるメモリマップとアンマップが繰り返される)

SMB 1.0

SMB も問題だよね,と.

  • SMB 1.0 ではパフォーマンスがでないよ.
    • 何が悲惨って……
      • SMB はパイプライニングできないよ.一回パケットを送ったら,成功が返ってくるまで次を送れないよ.
      • パケットサイズが 60 KB だよ.
    • 広帯域で遅延の大きなネットワークのときが一番悲惨だよ

そして Vista RTM 版で何を行ったか,何が行われなかったか

  • Large I/O が使えるようになったよ.
    • 今までの Windows だとディスクへの読み書きが結局 64 KB 単位に制限されてたよ.
    • Vista 無印からもっと大きな単位でディスクに読み書きできるようになったよ.
  • Cached I/O をやめてAsynchronous Non-Cached I/O に移行するよ.
    • Large I/O も併用するよ.
    • でも常に Non-Cached I/O だと色々問題があることがわかったので一部は Cached I/O を併用するよ.

続く

おすすめ本

インサイド Microsoft Windows 第4版〈上〉 (マイクロソフト公式解説書)

インサイド Microsoft Windows 第4版〈上〉 (マイクロソフト公式解説書)


インサイドMicrosoft Windows第4版〈下〉 (マイクロソフト公式解説書)

インサイドMicrosoft Windows第4版〈下〉 (マイクロソフト公式解説書)

  • 作者: ディビットソロモン,マークルシノビッチ,David A. Solomon,Mark E. Russinovich,豊田孝
  • 出版社/メーカー: 日経BPソフトプレス
  • 発売日: 2005/10
  • メディア: 単行本
  • 購入: 2人 クリック: 12回
  • この商品を含むブログ (30件) を見る

Windows® Internals, Fifth Edition (PRO-Developer)

Windows® Internals, Fifth Edition (PRO-Developer)

更新履歴

*1:『[http://builder.japan.zdnet.com/sp/vista-tips/story/0,3800083683,20368908,00.htm:title=もう1つの「Vista SP1」対「XP SP2」ベンチマーク]』という検証記事も出ています

*2:これは CreateFile で FILE_FLAG_SEQUENTIAL_SCAN を使用している場合の挙動.通常は 2 回のアクセス位置から 3 回目を予想するので,最初の 2 回の読み出しは先読みされない(11.7.1 『インテリジェントな先読み』).

*3:11.7.2『書き戻しキャッシングと怠慢なライタ』および 11.7.3『書き込みの抑制』.FILE_ATTRIBUTE_TEMPORARY を使うと本当に追い詰められるか明示的なフラッシュ指示があるまでデータを書き出さなくなる.

*4:Joel が先日言っていたことはまさにこれなんだと思っています. id:matarillo:20080214:p1 とか参考に.

Windows VIA C/C++ , Fifth Edition

ネタもと: MSDN フォーラム » Visual Studio » Visual C++ フォーラム » 最近の C/C++ & Windows 本
にゃんですとー!
いわゆるひとつのバイブル,『Advanced Windows』の第 5 版が出てたっぽい.

Windows® via C/C++, Fifth Edition (PRO-Developer)

Windows® via C/C++, Fifth Edition (PRO-Developer)


完全ノーマークでした.Mark Russinovich 氏の Inside Microsoft Windows Fifth Edition はばっちり警戒中なんですが,こっちはまだ音沙汰なし.

F# 本とか XNA 本とか

Expert F# の配送予定日ですがまだ確保できていません」という哀しいメールが届いたので腹いせに『Microsoft XNA Unleashed 日本語版』も買い物かごに放り込んでみたり.
最近ちょっと読むペースと買うペースのバランスがまずいかも.ガウディ本が読んでも読んでも終わらない.



Expert F# (Expert's Voice in .NET)

Expert F# (Expert's Voice in .NET)


Microsoft XNA Unleashed ―グラフィックスとゲーム開発―

Microsoft XNA Unleashed ―グラフィックスとゲーム開発―

おすすめ F# 本

なんか某所でまた F# が盛り上がっていますが,最近読んでいる F# 本が激しく良いのでご紹介.

Foundations of F# (Expert's Voice in .NET)

Foundations of F# (Expert's Voice in .NET)


何より素晴らしいのが,この手の技術書の中でも破格に読みやすい英語で書かれていることです.むしろ英語文章の教材にでもしたいぐらい.
おそらくこの本が一番向いているのは,.NET や C# をそこそこ知っている人が,関数型言語の入門書として最初に読んでみる,というケースでしょう.その用途だと『ふつうのHaskellプログラミング』よりもこっちの F# 本をおすすめします.
内容も豊富です.そして解説の順序がすばらしいので,分量が多いからといってそれほど苦にはなりません.細かい章立ては ここ で本文抜粋の PDF ファイルが公開されています.

CHAPTER 1 Introduction
CHAPTER 2 How to Obtain, Install, and Use F#
CHAPTER 3 Functional Programming
CHAPTER 4 Imperative Programming
CHAPTER 5 Object-Oriented Programming
CHAPTER 6 Organizing, Annotating, and Quoting Code
CHAPTER 7 The F# Libraries
CHAPTER 8 User Interfaces
CHAPTER 9 Data Access
CHAPTER 10 Distributed Applications
CHAPTER 11 Language-Oriented Programming
CHAPTER 12 The F# Tool Suite and .NET Programming Tools
CHAPTER 13 Compatibility and Advanced Interoperation

だいたい5章ぐらいまでで文法の基礎紹介がテンポ良く続き,第6章でメタプログラミングの顔見せ,第7章でライブラリの解説と続きます.その後は興味のあるところをつまみ食いしていくとよさげ.WinForms や,WPFWCF,LINQ との連携についても触れられています.
個人的には第11章がツボで,Quoting を使ったメタプログラミング (C# 3.0 の Expression Tree 生成機能のように,F# の式も Quote によって木構造をもったデータに変換できます) なんていう話が登場します.他にも簡易計算言語を作るために,文法から Parser を自動生成し,DynamicMethod を使って IL を出力したりという話も.
後は12章がツールの紹介,13章が相互運用で,たとえば F# で定義した Union を C# からどうやって使うかといった話が続きます.
とりあえず第1章がサンプルとして公開 されていますので,これだけ読んでみるというのもありでしょう.
また,微妙にそこそこ日本でも売れているのか Amazon.co.jp にはまだ在庫があるようです.いまボタンを押せば 2 名様限定ですぐに手に入る模様.
本の購入者向けの追加サービスとして $10 で PDF 版が販売されているので,読了後もプログラミング時のオンラインヘルプ代わりに使えます.
http://www.apress.com/promo/tendollars/
とまあこれから F# を始めようという人には是非おすすめの一冊でした.てかこれ,日本語訳に向けてあちこち動いてみてもいい本ですな.

仮想メモリ戦略に関する大きな誤解

PC Watch』の記事なんですが……うーん.

過去のWindowsに搭載されていたメモリ管理技術は、物理メモリの空き容量がない状態で、アプリケーションからメモリの要求があった際、メモリ上の最近利用されていないデータをHDD上のページファイルに移動させることで、メモリを解放していた。つまり、要求に応じたページング(On-demand Paging)となる。

ReadyBoost は比較的注目されているようで,こういう記事が出ること自体は望ましいことなんだと思いますが,「スワップ」のイメージに引きずられてしまっているのか,肝心の出発点の時点で大きく本質を見誤ってしまっているように思います.
引用部分の説明で何の疑問も抱かなかった人は多分同様の勘違いをしているのでご注意を.
とはいえここまで誤ったイメージが広がってしまうと,もはや全国の情報学科の学生が総出で解説を書いても払拭は無理なのかもしれませんけど.というかこういう記事でますます誤ったイメージが広がっていそうな気がします.
ReadyBoost の解説を書くのなら,せめて『インサイド Microsoft Windows 第4版』の内容はおさえておかないと難しいのではないでしょうか.

インサイド Microsoft Windows 第4版〈上〉 (マイクロソフト公式解説書)

インサイド Microsoft Windows 第4版〈上〉 (マイクロソフト公式解説書)


インサイドMicrosoft Windows第4版〈下〉 (マイクロソフト公式解説書)

インサイドMicrosoft Windows第4版〈下〉 (マイクロソフト公式解説書)

  • 作者: ディビットソロモン,マークルシノビッチ,David A. Solomon,Mark E. Russinovich,豊田孝
  • 出版社/メーカー: 日経BPソフトプレス
  • 発売日: 2005/10
  • メディア: 単行本
  • 購入: 2人 クリック: 12回
  • この商品を含むブログ (30件) を見る