特集 : Windows Server 2008

Windows Server 2008 カーネルの変更について

Mark Russinovich

 

概要:

  • メモリ管理と SMB 2.0
  • NTFS 自己復旧、Windows Hardware Error Architecture、およびドライバの検証ツール
  • I/O 完了ポート、スレッド プール、および NUMA によるスケーラビリティの向上
  • Hyper-V による仮想化

Windows Server 2008 は、マイクロソフト サーバー プラットフォームの最新リリースです。Windows Server 2008 には、オペレーティング システムの機能領域すべてに及ぶシステム レベルの変更が施されています。たとえば、メモリ管理、スレッドのスケジュール、ネットワーク、セキュリティなど、

影響のある機能領域は多岐に渡ります。

Windows Server® 2008 のカーネルは Windows Vista® SP1 と同じなので、Windows Server 2008 には、私が以前に TechNet Magazine の記事「Windows Vista カーネルの内部」の第 1 ~ 3 部 (2007 年 2 月号、3 月号、4 月号) および「Windows Vista ユーザー アカウント制御の内部」(2007 年 6 月号) で取り上げた機能強化の多くが含まれています。これらの記事で説明した機能の中で、クライアント専用の機能で Windows Server 2008 に含まれていないのは、SuperFetch、ReadyBoost、ReadyDrive、ReadyBoot、マルチメディア クラス スケジューラ サービス (MMCSS) など、ほんの一部の機能です。

この記事では、Windows Vista で導入され、Windows Server 2008 でも導入されているカーネルの重要な変更 (I/O の優先順位付け、新しいブート アーキテクチャ、BitLockerTM、コードの整合性、必須整合性レベルなど) について再度説明するのではなく、信頼性、パフォーマンス、およびスケーラビリティに関連する変更、新しいマイクロソフト ハイパーバイザ コンピュータ仮想化テクノロジである Hyper-VTM など、これらの記事で取り上げなかった主要な変更に重点を置いて説明します。

また、以前の記事と同様、この記事で取り上げる範囲は、オペレーティング システムのカーネル (Ntoskrnl.exe) および密接な関連があるシステム コンポーネントに限られます。インストール (WIM (Windows® Imaging Format) やコンポーネント ベース サービシング)、管理 (グループ ポリシーや Active Directory® の機能強化)、全般的な診断や監視 (Windows 診断インフラストラクチャ)、コア ネットワーク (ファイアウォールや TCP/IP の新しい実装)、Server Core、またはサーバーの役割への変更などについては、取り上げません。

マルチプロセッサ システムで機能する

システムの低レベルでの変更の 1 つは、Windows Server 2008 にはマルチプロセッサ システムで機能するように設計されたバージョンのカーネルのみが搭載されるということです。以前は、CPU が 1 基だけ搭載されているコンピュータを対象としたユニプロセッサ専用バージョンの Windows が使用されていました。このバージョンでは、マルチプロセッサ環境でのみ必要となる同期コードが省略され、パフォーマンスを少し向上させることができました。ただし、ハードウェアの速度の向上により、最適化によるパフォーマンス上のメリットは、ごくわずかになりました。また、現在ではほとんどのサーバー システムに複数のプロセッサが搭載されています。これらの理由により、ユニプロセッサ バージョンは不要になりました。

図 1 に、さまざまな Windows Server 2008 カーネルを示します。オペレーティング システムはデバッグ (チェック) 版と製品版のどちらであるか、インストールは 32 ビットと 64 ビット (Itanium、Intel 64、または AMD64) のどちらであるか、さらに、32 ビット インストールの場合は、システムの物理メモリのサイズが 4 GB を超えるか、またはシステムがデータ実行防止 (DEP) をサポートしているかによって、システムで使用されるバージョンが決まります。また、Windows Server 2008 は、32 ビット版の Windows Server オペレーティング システムが提供される最後のバージョンであることが予想されています。

Figure 1 さまざまな Windows Server 2008 カーネル

カーネル 32 ビット 64 ビット
マルチプロセッサ
マルチプロセッサ、チェック版
マルチプロセッサ、物理アドレス拡張 (PAE) ×
マルチプロセッサ、PAE、チェック版 ×

Windows Server のすべてのリリースでは、ファイル サービング、ネットワーク I/O、メモリ管理などの主要なサーバー シナリオのパフォーマンス向上に重点を置いてきました。さらに、Windows Server 2008 では、新しいハードウェア アーキテクチャの利用、待ち時間の長いネットワークへの適応、および以前のバージョンの Windows でパフォーマンスを制限していたボトルネックの解消を実現するための、いくつかの変更や新機能が用意されています。ここでは、メモリ マネージャや I/O システムの機能強化を概説し、新しいネットワーク ファイル システムである SMB 2.0 を紹介します。

メモリ管理

試してみよう : サイズの大きなディスク I/O を確認する

TechNet からダウンロードできる Sysinternals Process Monitor (technet.microsoft.com/sysinternals/bb896645.aspx) などのファイル システム監視ツールを使用すると、Windows Server 2008 システムでサイズの大きなファイル I/O 処理を探すことができます。

サイズの大きな I/O を発生させる方法は、いくつかあります。Windows Vista Service Pack 1 または Windows Server 2008 を実行している別のシステムがある場合は、サーバー上で Process Monitor を実行して、別のシステムへのファイル コピー処理を監視することができます。また、通常、メモリを大量に使用するプログラムを実行すると、メモリ マネージャによってページング ファイルにページが書き込まれ、サイズの大きなページング ファイル I/O を発生させることができます。

図 A に、メモリを大量に使用するプログラムを Windows XP システムで実行した後の Process Monitor の状態を示します。この例では、Process Monitor の [Options] (オプション) メニューの [Enable Advanced Output] (高度な出力を有効にする) をオンにし、また、ページング ファイル (pagefile.sys) への書き込みだけを表示するようにフィルタを設定しました。[Detail] (詳細) 列では、書き込みのサイズが 64 KB であることが示されています。

図 A

図 A  (画像を拡大するには、ここをクリックします)

同じ手順を Windows Server 2008 で実行すると、おそらく、図 B に示すような内容が表示され、ほとんどの書き込みのサイズが約 1 MB であることが示されています。

図 B

図 B  (画像を拡大するには、ここをクリックします)

Windows Server 2008 では、メモリ マネージャにパフォーマンス上の機能強化がいくつか施されています。たとえば、ページング ファイルからデータを取得したり、マップされたファイルに対して先読み I/O を実行したりする際に、Windows Server 2008 のメモリ マネージャが実行するディスク I/O は、Windows Server 2003 よりも、回数は少なく、サイズは大きくなります。ファイル I/O のサイズの増大は、Windows NT® の最初のリリース時から存在する 64 KB という I/O サイズの制限が廃止されたという、I/O システムの変更により実現されました。

また、キャッシュ マネージャによる、先読み (推測的な読み取り) のための、マップされたファイルからのデータ読み取りのサイズは、通常、Windows Server 2008 では Windows Server 2003 の 2 倍のサイズであり、スタンバイ リスト (システムのコードやデータのキャッシュ) の内容が直接読み取られることにも注意してください。この動作により、キャッシュ マネージャでは、仮想メモリをマップしてデータをシステムのワーキング セット (メモリ マネージャによってシステムに割り当てられたメモリ) に読み込むという処理が不要になります。以前の動作では、他の使用中のコードやデータが不必要にワーキング セットから削除される可能性がありました。

メモリ マネージャでページング ファイルにデータが書き込まれる際にも、サイズの大きな I/O が実行されます。Windows Server 2003 では 64 KB 未満の書き込みが行われることも珍しくありませんでしたが、Windows Server 2008 のメモリ マネージャでは、通常、1 MB の書き込みが行われます。

ページング ファイルへの書き込みの回数の減少によりパフォーマンスが向上することに加えて、書き込みのサイズが大きくなることによりページング ファイル内の断片化が軽減されます。また、多くの場合、複数のページが近接するようになるので、複数のページを読み取るのに必要な読み取りの回数やディスク シークの回数が減少します。

メモリ マネージャでは、所有プロセスのアドレス空間に書き込まれているページに近接している他の変更されたページの書き込みも行います。また、書き込みを行う際には、ページング ファイルの他の近接しているページが既に存在する領域を対象とします。この動作によっても断片化が最小限に抑えられ、今後ページング ファイルに書き込まれる可能性のあるページが既に書き込まれているので、パフォーマンスの向上にもつながります。さらに、近接しているプロセス ページ範囲を読み取るのに必要な、ページング ファイルの読み取りの回数が減少します。メモリ マネージャによるサイズの大きな I/O の使用の詳細については、補足記事「試してみよう : サイズの大きなディスク I/O を確認する」を参照してください。

SMB 2.0

サーバー メッセージ ブロック (SMB) リモート ファイル システム プロトコルは、共通インターネット ファイル システム (CIFS) とも呼ばれ、ファイル サービング機能が Windows に導入されて以来、Windows のファイル サービングの基盤となっています。ただし、ここ数年間、SMB の設計上の制限によって、Windows のファイル サービングのパフォーマンスが制限され、新しいローカル ファイル システム機能が十分に活用されていませんでした。たとえば、1 つのメッセージで転送できる最大バッファ サイズは約 60 KB で、SMB 1.0 では Windows Vista と Windows Server 2008 で導入された NTFS クライアント側シンボリック リンクには対応していませんでした。

Windows Vista と Windows Server 2008 では SMB 2.0 が導入されています。これは、クライアントとサーバーの両方でサポートされる場合に Windows で使用される新しいリモート ファイル サービング プロトコルです。SMB 2.0 では、クライアント側シンボリック リンクと他の NTFS 機能強化が適切に処理されることに加えて、クライアントとサーバーの間で交換されるメッセージの数を最小限に抑えるためにバッチ処理が使用されます。バッチ処理を使用すると、一度にやりとりできるデータの量が多くなるので、ワイド エリアネットワーク (WAN) など、待ち時間の長いネットワークでのスループットが向上します。

SMB 1.0 では 1 つのファイルに対する I/O は逐次的に実行されましたが、SMB 2.0 では、I/O のパイプライン処理が実装されているため、同じファイルに対して複数の I/O を同時に実行することができます。また、パイプラインの深さの程度を判断するために、クライアントがサイズの大きな I/O に使用するサーバー メモリの量が測定されます。

Windows I/O メモリ マネージャと I/O システムの変更、TCP/IP 受信ウィンドウ自動チューニングの変更、およびファイル コピー エンジンの強化により、SMB 2.0 では、スループットが大幅に向上し、サイズの大きな転送においてファイルのコピーにかかる時間が短縮されます。Windows Server 2008 ファイル サーバーを Windows Vista クライアントと共に展開すると、両方のオペレーティング システムで SMB 2.0 が実装されるので、SMB 2.0 を使用することができ、このようなパフォーマンス上のメリットを享受できます。

NTFS 自己復旧による信頼性の強化

信頼性はサーバーの重要な特質であり、Windows Server 2008 では、オンラインの NTFS 整合性修復、新しいハードウェア エラー報告インフラストラクチャ、ドライバの検証ツールの機能拡張など、管理者がサーバーの正常な稼動状態を維持するのに役立つさまざまな機能強化が施されています。

現在の数テラバイト (TB) ものサイズがある記憶装置では、整合性チェックを行うためにボリュームをオフラインにすると、サービスが数時間停止することになります。ディスク破損の原因の多くは 1 つのファイルやメタデータの一部に限局されるという事実により、Windows Server 2008 では、ボリュームがオンライン状態のときに破損を修復する新しい NTFS 自己復旧機能が実装されています。

この NTFS 自己復旧機能により破損が検出されると、破損したファイルへのアクセスが阻止され、破損したデータ構造に対して Chkdsk のような修復を実行するシステム ワーカー スレッドが作成されます。修復が完了すると修復されたファイルにアクセスできるようになります。この処理の間も他のファイルには通常どおりアクセスすることができるので、サービスの中断は最小限に抑えられます。

WHEA インフラストラクチャ

Windows Server 2008 に組み込まれている Windows Hardware Error Architecture (WHEA) インフラストラクチャを使用すると、ハードウェア障害の管理が簡略化され、致命的でないエラーに事前に対応できるようになります。多くの場合、高い稼働率が要求されるサーバー システムでは、タイムリーにエラーを特定して対応することが非常に重要です。

オンライン クラッシュ ダンプ解析サービス (OCA) を通じてマイクロソフトに送信されたクラッシュの分析から、オペレーティング システムのクラッシュの約 10% はハードウェア障害によるものであることが判明しています。しかし、クラッシュ時にハードウェアから提供されるエラー情報は不十分なので、このようなクラッシュの根本原因を突き止めることは困難または不可能でした。また、Windows Server 2008 よりも前のバージョンの Windows では、デバイスの状態の監視は組み込みでサポートされておらず、差し迫っている障害の修復や通知は実装されていませんでした。これは、ハードウェア デバイスでは共通のエラー形式が使用されておらず、エラー管理ソフトウェアがサポートされていないことが原因でした。

WHEA では、エラー ソースの発見と報告の統一メカニズムをプラットフォーム デバイス (プロセッサ、メモリ、キャッシュ、PCI や PCI Express などのバスを含む) に提供します。これは、図 2 に示すアーキテクチャが WHEA に実装されることにより実現されます。ここで中核となるのは、エラー ソースがエラーを報告するために呼び出すカーネル API です。この API を使用するには、すべてのエラーが共通の形式になっている必要があります。この API では、Event Tracing for Windows (ETW) イベントを使用してエラーがログに記録されます (致命的なエラーは再起動後にログに記録されます)。

図 2 WHEA エラー報告インフラストラクチャ

図 2** WHEA エラー報告インフラストラクチャ **(画像を拡大するには、ここをクリックします)

ETW は Windows 2000 で導入されました。WHEA で ETW が使用されることにより、ハードウェア メーカーやソフトウェア ベンダは、WHEA イベントを使用するデバイス診断管理アプリケーションを容易に開発できるようになります。発生したイベントがシステムのクラッシュの原因となるほど重大度が高い場合は、管理者がクラッシュの根本原因を特定できるように、WHEA によって致命的なエラーの記録がクラッシュ ダンプ ファイルに保存されます。

WHEA のもう 1 つの主要な要素は、%Systemroot%\System32\Pshed.dll に含まれているプラットフォーム固有のハードウェア エラー ドライバ (PSHED) です。カーネルは PSHED と連携して、プラットフォームおよびファームウェア ハードウェアとのインターフェイスとなって、実質的には、このエラー通知と WHEA エラー報告 API との間の変換層としての機能を果たします。マイクロソフトでは、各プラットフォーム アーキテクチャ (x86、x64、Itanium) 用の PSHED を用意しています。また、PSHED では、ハードウェア ベンダやメーカーが既定の動作を各社のプラットフォームに固有の動作で置き換えることができるように、プラグイン モデルを公開しています。

また、他のエラー ソースとのインターフェイスとなるシステム コンポーネント (デバイス ドライバ、ハードウェア アブストラクション レイヤ (HAL)、カーネルなど) には、エラー状態を最初に処理する低レベル ハードウェア エラー ハンドラ (LLHEL) を実装することができます。LLHEL の役目は、デバイスからエラー情報を抽出し、追加のプラットフォーム エラー情報の収集を許可するよう PSHED に通知し、カーネルの WHEA エラー報告 API を呼び出すことです。

ドライバの検証ツール

ドライバの検証ツールは、Windows 2000 以降のすべての Windows に組み込まれている、バグのあるデバイス ドライバや欠陥のあるハードウェアを突き止めるための強力なツールです。通常、管理者は、システムのクラッシュを引き起こした可能性があるデバイス ドライバの動作を厳重に監視するようにドライバの検証ツール (%Systemroot%\System32\Verifier.exe) を構成します。ドライバの検証ツールを使用すると、不適切なドライバ操作が検出され、問題があるものをクラッシュ ダンプ ファイルで直接特定できます。

以前のドライバの検証ツールには、ほとんどの構成変更でシステムの再起動が必要になるという欠点がありました。これは、運用サーバーでは明らかに望ましくない動作です。Windows Server 2008 で実装されたドライバの検証ツールでは、この処理が改善され、再起動が不要になり、最も実用的な検証が実現されます。この動作により、問題のあるサーバーを再起動せずにトラブルシューティングを行うことが可能になります。

また、ドライバの検証ツールには、図 3 に示す 3 つの新しい検証機能が導入されています。セキュリティの検査を使用すると、デバイス ドライバがアプリケーションとのインターフェイスに使用するオブジェクトに、過不足ないアクセス許可が設定されます。保留中の I/O 要求の強制を使用すると、遅れてではなく直ちに完了する非同期 I/O 処理に対する、ドライバの回復性が検査されます。その他の検査を使用すると、使用中のリソースを間違って解放しているドライバ、Windows Management Instrumentation (WMI) 登録 API を不適切に使用しているドライバ、およびリソース ハンドルをリークしているドライバを検出できます。

図 3 Windows Server 2008 で導入されたオプションがオンになった状態のドライバの検証ツール

図 3** Windows Server 2008 で導入されたオプションがオンになった状態のドライバの検証ツール **(画像を拡大するには、ここをクリックします)

スケーラビリティ

スケーラビリティとは、オペレーティング システムやアプリケーションが複数のプロセッサや大量のメモリを効果的に利用する能力のことです。Windows では、新しいリリースのたびに、マルチプロセッサでの並列処理を減少させるロックの使用を最小限に抑えたり、廃止したりすることによって、スケーラビリティが向上しています。Windows Server 2008 も、この傾向の例外ではありません。

比較的小規模ですが重要な機能強化は、タイマを終了させるコードに実装されており、ディスパッチャ ロック (すべての低レベルの同期処理で使用される、システム全体に及ぶスケジューラ ロック) の取得が行われなくなりました。その結果、CPU の同期オーバーヘッドが削減され、Windows Server 2008 ターミナル サーバー システムでは同時にサポートできるユーザーの数が Windows Server 2003 よりも約 30% 多くなります。

Windows Server 2008 での、スケーラビリティに関する他の機能強化には、完了ポートの機能拡張、スレッド プールの新しい実装、Non-Uniform Memory Access (NUMA) ハードウェアのより効率的な使用、システムの動的なパーティション分割などがあります。

I/O 完了ポート処理の強化

IIS、SQL Server®、Exchange Server など、スケーラブルな Windows サーバー アプリケーションのほとんどでは、I/O 処理を実行する際、複数の実行スレッド間の切り替えを最小限に抑えるために、完了ポートと呼ばれる Windows 同期 API を使用しています。これは、まず新しい要求の着信の通知 (Web サーバー クライアントの接続など) を完了ポートと関連付け、通知を待機させるためのスレッドのプールを確保することによって行われます。要求が着信すると、スレッドがスケジュールされ、通常、そのスレッドによって、他の I/O 処理 (Web ページをディスクから読み取ってそれをクライアントに送信するなど) が実行され、要求が完了します。

同じスレッドができるだけ早くクライアント要求を待機している状態に戻ることができるように、スレッドは I/O を非同期に実行し、I/O の完了を完了ポートと関連付けます。次に、スレッドは完了ポートで待機している状態に戻り、新しい要求が着信するか I/O の 1 つが完了すると、スレッドがスケジュールされます。このようにして、同じスレッドが、クライアント要求の処理と完了ポートでの待機を交互に行いながら、CPU 上でアクティブな状態を維持します。

以前の Windows リリースの完了ポートには、I/O が完了すると、その I/O を実行したスレッドが他の処理を実行中でも、そのスレッドで直ちにちょっとした完了処理が実行されるという欠点がありました。また、他のスレッドがアクティブな場合は、アクティブなスレッドから I/O を実行したスレッドへのコンテキストの切り替えが頻繁に行われていました。

Windows Server 2008 では、この完了処理が、I/O が関連付けられている完了ポートで待機する次のスレッドで行われることによって、このようなコンテキストの切り替えが回避されます。したがって、完了ポートで待機する次のスレッドが別のスレッドである場合も、その別のスレッドは他のコードを実行する前に完了処理を実行するので、I/O を実行したスレッドへの切り替え処理は不要です。こうしてコンテキストの切り替えを最小限に抑えることで、負荷の高いサーバー アプリケーションのスケーラビリティが大幅に向上します。

より効率的なスレッド プール

複数の CPU を利用するアプリケーションを記述するのは難しい場合があるので、Windows XP では、ワーカー スレッド プールが導入されました。これはインフラストラクチャと関連 API で、この API では小さな単位の作業を複数の CPU で実行する方法の詳細が抽象化されています。アプリケーションで作業項目をスレッド プール API に指定すると、この API では、システムに搭載されている各 CPU に対して作成および管理された複数のスレッドのうちの 1 つで作業項目を実行します。

スレッド プールは、同じスレッドを使用して複数の作業項目を連続して実行することにより、コンテキストの切り替えを最小限に抑えることを目的としています。スレッドの 1 つが既に他の作業を実行していてビジー状態になっているという理由で、同じスレッドを使用することができない場合、作業項目は、別の CPU の別のスレッドを使用して実行されます。

Windows Server 2008 のスレッド プールの実装では、CPU がより有効に利用されます。その間接的な理由は、完了ポートの機能強化によるメリットを享受するからです。また、直接的な理由は、アプリケーションのワークロードを処理する必要があるときにワーカー スレッドが動的に使用されるように、スレッドの管理が最適化されるからです。さらに、インフラストラクチャの中核がカーネル モードに移行したので、API を使用するアプリケーションによるシステム呼び出しの回数が最小限に抑えられます。また、この新しい API を使用すると、アプリケーションでは、特定の処理 (アプリケーションのシャットダウン中にキューに格納された作業単位の実行を中止するなど) をより容易に実行できます。

NUMA の最適化

Windows Server 2003 では、NUMA コンピュータの最適化がスレッド スケジューラとメモリ マネージャに導入されましたが、Windows Server 2008 では、NUMA の最適化が I/O マネージャでも行われるようになり、メモリ マネージャによる NUMA の最適化が拡張されています。

通常、NUMA システムは、アクセスするプロセッサによってメモリの待ち時間が異なるマルチプロセッサ システムです (図 4 参照)。メモリはノードに分割されます。CPU からノードへのアクセスにかかる待ち時間はさまざまで、各 CPU は、その CPU が最速でアクセスできるノードの一部と見なされます。

図 4 NUMA システムの例

図 4** NUMA システムの例 **(画像を拡大するには、ここをクリックします)

NUMA システム、とりわけ搭載されている CPU の数が 8 基を超える NUMA システムは、多くの場合、均質メモリ アクセス (Uniform Memory Access) システムよりもコスト効率やパフォーマンス効率が高くなります。均質メモリ アクセス システムでは、メモリはすべての CPU で同様に使用できる必要がありますが、NUMA システムでは、CPU に直接接続されているメモリに対しては高速な相互接続を実装し、直接接続されていない CPU やメモリに対しては安価で待ち時間の長い接続を実装することができます。

NUMA システムで高いパフォーマンスを実現するには、オペレーティング システムやアプリケーションがノード トポロジに対応している必要があります。ノード トポロジに対応していると、処理は、データやコードが格納されているメモリの近くで実行されるようになります。たとえば、Windows スケジューラでは各スレッドに、"最適なプロセッサ" (スケジューラが常にそこでスレッドを実行しようとする CPU のこと) を割り当てます。このような割り当てにより、スレッドが CPU のキャッシュに格納するデータは、スレッドの実行時に、スレッドで使用できる確率が高くなります。

Windows Server 2003 のスケジューラでは、この概念が拡張され、最適なプロセッサが含まれているノードがスレッドに最適なノードと見なされます。また、最適なプロセッサが別のスレッドの処理でビジー状態になっている場合は、最適なノード内の別の CPU にスレッドをスケジュールします。Windows Server 2003 のメモリ マネージャも NUMA に対応するようになり、可能であれば、スレッドに割り当てられているメモリをスレッドが実行されているノードのメモリに割り当てます。

Windows Server 2008 のメモリ マネージャでは、カーネルの非ページ メモリ バッファ (RAM 内に確実に残るデータを格納するためにカーネルとデバイス ドライバによって使用されるメモリ) がノード間で分配されます。そのため、スレッドには、ノードに割り当てられているメモリからメモリが割り当てられます。システムのページ テーブル エントリ (PTE) は、メモリの割り当てに新しいページ テーブル ページが必要な場合は、割り当て元であるノードから割り当てられます。これは他のノードから割り当てられる Windows Server 2003 の場合と異なります。

Windows Server 2003 では、スレッドでメモリ割り当てを行う場合、メモリ マネージャは、割り当て時にスレッドが実行されているノードを優先していました。スレッドが、少しの間、最適でないノードにスケジュールされると、その間に行われたすべての割り当ては、最適でないノードから割り当てられます。そのため、スレッドが後で最適なノードで実行されたときに、データやコードは割り当てられたメモリに格納されているので、近接した状態で実行されません。

この問題に対処するため、Windows Server 2008 のメモリ マネージャでは、すべてのスレッドの割り当てで、スレッドの最適なノードが優先されるようになりました。スレッドが別のノードの近くで実行されている場合も同様です。また、メモリ マネージャでは、プロセッサからノードへのアクセスにかかる待ち時間が自動的に計算されるので、使用できるメモリが最適なノードにない場合は、最適なノードの最も近くにあるノードがチェックされます。さらに、スレッドがコードやデータを参照するときには、スタンバイ リスト内のページをスレッドの最適なノードに移動します。

割り当ての場所を制御する必要があるアプリケーションでは、新しい NUMA メモリ API を使用して、メモリ割り当て、ファイル マッピング ビュー、およびファイル マッピング オブジェクト用の優先ノードを指定できます。ファイル マッピングに関連する割り当てでは、メモリ マネージャは、マッピング処理でノードが指定されているかどうかをチェックし、次にファイル マッピング オブジェクトでノードが指定されているかどうかをチェックし、どちらでも指定されていない場合は、スレッドの最適なノードに割り当てます。

Windows Server 2008 より前のバージョンでは、記憶域 I/O やネットワーク I/O の割り込みおよび関連付けられた遅延プロシージャ呼び出し (DPC) は、I/O が開始されたノード以外のノードの CPU を含む任意の CPU で実行できました。そのため、I/O 処理で読み書きされるデータが、データへのアクセスが行われているノード以外のノードのメモリに存在することがありました。

この状況を回避するために、Windows Server 2008 の I/O システムでは、I/O を開始したノード内の CPU で DPC が実行されるようになります。また、PCI バス MSI-X (メッセージ シグナル割り込み標準の機能拡張) をサポートしているデバイスが接続されたシステムでは、Windows Server 2008 の API を利用するデバイス ドライバを使用し、I/O を開始したプロセッサで I/O の割り込み処理を実行して、I/O 完了をさらに限局することができます。

動的なパーティション分割

システムのスケーラビリティを向上させる方法の 1 つは、CPU やメモリなどのハードウェア リソースをシステムに動的に追加できるようにすることです。システムを再起動することなく、ハードウェア リソースを交換できる場合、この動的なリソース追加のサポートによりシステムの可用性も高まります。

Windows Server 2003 ではコンピュータの電源を入れたままでメモリを追加することができるので、動的なメモリをサポートしているサーバーでは管理者がメモリを追加すると RAM を使用できるようになりました。Windows Server 2008 では、動的なメモリのサポートが拡張され、メモリの交換が可能になりました。

エラー修正コード (ECC) による修正への依存度が高くなる RAM は、まったく機能しなくなる危険性があるので、コンピュータの電源を入れたままでのデバイス交換をサポートしているサーバーでは、Windows Server 2008 は、正常に機能していないメモリ バンクから代替のメモリ バンクにデータを透過的に移動することができます。これは、オペレーティング システムの制御下にあるデータをまず移動し、次にハードウェア デバイスを低電力状態にすることでハードウェア デバイスを実質上停止し、メモリ内の残りのデータを移動し、最後に通常の運用を継続するためにデバイスに電力を再供給することによって行われます。

Windows Server 2008 では、コンピュータの電源を入れたままでプロセッサを追加または交換することもできます。コンピュータの電源を入れたままでデバイス交換を行うには、ハードウェアが予備の CPU という概念をサポートしている必要があります。これは、既存の CPU から障害の通知が生成されたときにオンラインで提供したり動的に追加したりすることができるもので、現在はハイエンド システムのみで利用できます。Windows Server 2008 のスケジューラでは、正常に機能していない CPU での処理の速度を落とし、その処理を代替 CPU に移行します。その後で、正常に機能していない CPU を取り外して新しい CPU と交換することができます。

Windows Server 2008 では、コンピュータの電源を入れたままでプロセッサを追加することができるので、管理者は、ダウンタイムを発生させることなくサーバーの処理能力を上げられます。ただし、一部のアプリケーションでは、ブート セッションのために CPU の数が固定されていることを想定しているため、このような新しい CPU を使用できるのは、新しい API を通じて CPU の追加の通知を要求しているデバイス ドライバやアプリケーションに限られます。たとえば、あるアプリケーションでは、各 CPU に対応する作業キューの配列を割り当てる可能性があり、その場合、スレッドでは、スレッドが実行される CPU に関連付けられたキューを使用します。スケジューラにより、アプリケーションのスレッドの 1 つが新しい CPU に配置されると、実在しないキューの参照が行われ、アプリケーションのデータが破損する可能性があり、おそらくはアプリケーションがクラッシュします。

SQL Server や Exchange Server など、マイクロソフトのサーバー ベースのアプリケーションは CPU の追加に対応しており、システム プロセス、セッション マネージャ (%SystemRoot%\System32\Smss.exe)、汎用サービス ホスト プロセス (%Systemroot%\System32\Svchost.exe) などのいくつかの中核的な Windows プロセスも CPU の追加に対応しています。他のプロセスでも、Windows API を使用して、新しい CPU の追加の通知を要求することができます。新しい CPU を追加すると、追加が間近に迫っていることがデバイス ドライバに通知され、CPU が起動されます。続いて、必要に応じて新しい CPU での操作を追跡するためにデータ構造を割り当てることができるように、新しい CPU を利用するように記述されたデバイス ドライバとアプリケーションに通知されます。

コンピュータの仮想化

Windows Server 2008 より前のバージョンでは、マイクロソフトの仮想化製品 (Virtual Server 2005 を含む) は、図 5 に示すように、仮想化した環境をホストすることで実装されていました。ホストされる仮想化では、バーチャル マシンは、Virtual Machine Monitor (VMM) によって実装されます。VMM は、ホスト オペレーティング システムと同時に、通常はデバイス ドライバとして実行されます。VMM はホスト オペレーティング システムのリソース管理とデバイス ドライバに依存しているため、ホスト オペレーティング システムで VMM の実行がスケジュールされると、アクティブなバーチャル マシン (VM) 間で CPU が時間で分配されます。

図 5 ホストされているコンピュータの仮想化

図 5** ホストされているコンピュータの仮想化 **(画像を拡大するには、ここをクリックします)

Hyper-V (コードネーム Viridian) は、ハイパーバイザ仮想化を使用して実装されます。ハイパーバイザはすべてのハードウェア リソースを完全に管理下に置き、システムをブートし VM を制御する Windows Server 2008 オペレーティング システムも実質的にはバーチャル マシン内で実行されます (図 6 参照)。

図 6 Hyper-V のアーキテクチャ

図 6** Hyper-V のアーキテクチャ **(画像を拡大するには、ここをクリックします)

ハイパーバイザでは、システムを複数の VM にパーティション分割することができ、Windows Server 2008 の起動インスタンスをマスタ パーティション (ルート パーティション) として扱い、ディスク、ネットワーク アダプタ、グラフィック プロセッサなどのハードウェア デバイスにルート パーティションから直接アクセスできるようにしています。ハイパーバイザでは、ルート パーティションにより、電源管理とハードウェアのプラグ アンド プレイ イベントへの対応が行われることを前提としています。ハイパーバイザは、子パーティションで開始されたハードウェア デバイス I/O をインターセプトし、それをルート パーティションに伝達します。ルート パーティションでは、ハードウェアへのアクセスに標準の Windows Server 2008 デバイス ドライバを使用します。このように、Hyper-V を実行しているサーバーでは、Windows によるハードウェア デバイスのサポートを最大限に利用できます。

Hyper-V サーバーの役割を使用して Windows Server 2008 を構成すると、hypervisorimagelaunchtypeboot というブート構成データベース (BCD) 設定が auto に設定され、Hvboot.sys デバイス ドライバが、ブート プロセスの早い段階で開始するように構成されます。このオプションが構成されると、仮想化に向けてシステムの準備が整えられ、%Systemroot%\System32\Hvax64.exe または %Systemroot%\System32\Hvix64.exe がメモリに読み込まれます。システムが実装している CPU の仮想化拡張機能が AMD-V の場合は前者、Intel VT の場合は後者が読み込まれます。

読み込みが完了すると、ハイパーバイザは、仮想化拡張機能によって Windows Server 2008 の下位に配置されます。ユーザー モード アプリケーションは x64 プロセッサの特権レベルのリング 3 を使用し、カーネル モード コードはリング 0 で実行されるので、ハイパーバイザは概念的な特権レベルのリング -1 で動作します (これは、ハイパーバイザはリング 0 で実行されているコードの実行環境を制御できることによるものです)。

Hyper-V 管理コンソールを使用して子パーティションを作成または起動すると、子パーティションは %Systemroot%\System32\Drivers\Winhv.sys ドライバを使用してハイパーバイザと通信します。このドライバでは、ドキュメントが公開されているハイパーコール API を使用して、特定の物理メモリ サイズで特定の実行特性を備えた新しいパーティションを作成するようにハイパーバイザに指示します。ルート パーティションにある VM サービス (%Systemroot%\System32\Vmms.exe) は、子パーティションの状態を管理するために子パーティションそれぞれについて VM ワーカー プロセス (%Systemroot%\System32\Vmwp.exe) を作成します。

子 VM オペレーティング システムのパフォーマンスが向上する要因の 1 つは、Windows Server 2008 と Windows Vista の両方で啓発コードが実装されていることです。これは、マイクロソフト ハイパーコール API を実装しているハイパーバイザ上でオペレーティング システムが実行されている場合にのみアクティブになるコード シーケンスです。子 VM では、ハイパーバイザのサービスを直接要求することにより、ハイパーバイザが子オペレーティング システムの目的を推測しなければならない場合に発生する仮想化コードのオーバーヘッドを回避します。

たとえば、(低レベルのマルチプロセッサ同期を実行する) スピンロックの啓発コードを実装していないゲスト オペレーティング システムは、他の仮想プロセッサがスピンロックを解放するのを待機するという指定された条件を満たせないループに陥ります。このループにより、ハイパーバイザが別の仮想プロセッサをスケジュールするまでハードウェア CPU の 1 つがビジー状態になることがあります。啓発コードが実装されているオペレーティング システムでは、このようなループに陥りそうになると、スピンロック コードにより、ハイパーコールを通じてハイパーバイザに通知されます。その結果、ハイパーバイザでは、すぐに別の仮想プロセッサがスケジュールされ CPU 使用率の浪費を削減することができます。

Windows Server 2008 で VM のパフォーマンスが向上するもう 1 つの要因は、VM からデバイスへのアクセスが高速化していることです。"VM 統合コンポーネント" と総称される一連のコンポーネントを子オペレーティング システムにインストールすると、パフォーマンスが向上します。

この統合コンポーネントをインストールせずに VM を実行すると、子オペレーティング システムでは、ハイパーバイザが提供するエミュレートされたデバイス用のハードウェア デバイス ドライバを構成します。デバイス ドライバがハードウェア リソースにアクセスする際には、ルート パーティションに通知するためにハイパーバイザが介入する必要があります。ルート パーティションは、標準の Windows デバイス ドライバを使用して子 VM のオペレーティング システムの代わりにデバイス I/O を実行します。ディスクからの読み取りなどの高レベルな単独の I/O 処理では、個別のハードウェア アクセスが多数伴うことがあるので、ハイパーバイザやルート パーティションに対して、インターセプトと呼ばれる遷移が多数発生することがあります。

Windows Server 2008 では、バーチャル マシン バス ドライバ (%Systemroot%\System32\Drivers\Vmbus.sys)、仮想サービス クライアント (VSC)、および仮想サービス プロバイダ (VSP) という 3 つのコンポーネントによって、インターセプトが最小限に抑えられます。統合コンポーネントを、サポートされているオペレーティング システムの VM にインストールすると、VSC はデバイス ドライバの役割を引き継ぎ、子 VM の Vmbus.sys ドライバのサービスを使用し、ハイパーコールとハイパーバイザのメモリ共有サービスを通じてルート パーティションのバーチャル マシン バス ドライバに高レベルな I/O 要求を送信します。ルート パーティションでは、Vmbus.sys によって対応する VSP に要求が転送され、ルート パーティションのデバイス ドライバを通じて標準の Windows I/O 要求が開始されます。

以上のように、Hyper-V ハイパーバイザ ベースの仮想化が導入された Windows Server 2008 は、マイクロソフトのコンピュータ仮想化戦略において重要な役割を果たします。こうした機能やその他の機能の詳細については、今年後半に発行を予定している、私の著書の次回エディション『Microsoft Windows Internals』を参照してください。

Mark Russinovich は、マイクロソフトのプラットフォーム & サービス部門に所属するテクニカル フェローです。また、『Microsoft Windows Internals』(Microsoft Press、2004) の共同執筆者であり、Microsoft TechEd や Professional Developer's Conference などの、IT カンファレンスや開発者向けカンファレンスで頻繁に講演を行っています。共同で設立した Winternals Software 社のマイクロソフトによる買収に伴い、マイクロソフトに入社しましたが、Sysinternals の設立者でもあり、同社では Process Explorer、Filemon、Regmon など、多くの人気のあるユーティリティを発表しています。

© 2008 Microsoft Corporation and CMP Media, LLC. All rights reserved; 許可なしに一部または全体を複製することは禁止されています.