Multimedia Class Scheduler Service (MMCSS) (3)

事前定義されたタスクの Clock Rate はいずれも 10000 となっていますが,これは 100 ns 単位なので 1 msec に対応します.このことから,MMCSS を有効化するとスレッドスケジューリングに使用される割り込み周期は少なくとも 1 msec 以下に再設定されることが予想されます.実際に実験してみました.テストには Windows Vista RC 1 日本語版,Thinkpad T60 を使用しました.
まず,この Vista RC 1 環境でのデフォルト状態でのタイマ割り込み間隔について見てみます.
Sleep(1) の呼出しから復帰する時間を観察すると,この環境のタイマ割り込みは約 15 msec のようでした.以前の Windows でも,x86 ユニプロセッサ環境では 10 msec,x86 マルチプロセッサ環境では 15 msec がデフォルトと言われていましたから*1,この値は妥当なものだと考えられます.
次に,timeBeginPeriod(1) を呼出したところ,Sleep(1) の呼出しは 1 msec 程度の時間で帰るようになりました.
実際に割り込み回数が変化していることは,Process Explorer からも分かります.

デフォルト状態
timeBeginPeriod(1)実行後

上が平常時で,下があるプロセスで timeBeginPeriod(1) を呼び出した後のものです.Interrupts の 1 秒間の Context Switch Delta が増えていることがおわかりになるかと思います.
ではいよいよ,MMCSS を使用してみましょう.timeBeginPeriod(1) を呼び出す代わりに,AvSetMmThreadCharacteristics API を使用してスレッドに Games タスクを割り当てたところ,やはり timeBeginPeriod(1) と同様の効果があることが分かりました.このことから,Windows Vista では timeBeginPeriod(1) よりも AvSetMmThreadCharacteristics を使用する方が行儀の良いプログラムと呼べるかもしれません.
もうひとつおまけです.事前定義されたタスクに "Window Manager" があることからも分かるように,MMCSS は Desktop Window Manager (DWM) も想定しています.しかし,Aero が有効な状態で行った最初の計測では割り込み間隔 15 msec のように振る舞っていたことから,デフォルトでは DWM は MMCSS を使用していないと考えられます.
DWM に MMCSS を使用させるには,DwmEnableMMCSS API に TRUE を渡します.この場合も,Sleep(1) の呼出しは 1 msec 程度の時間で帰るようになったことが確認できました.

まとめ

  • 現在の Windows の実装では,timeBeginPeriod(1) を呼び出すことで*2,スレッドスケジューリングの粒度が変化する.
  • Windows Vista では AvSetMmThreadCharacteristics を指定することで,timeBeginPeriod API の呼出しをより汎用的に置き換えることが出来る.
  • DWM に MMCSS を使用させるには,DwmEnableMMCSS API を使用する.

*1:『インサイド Microsoft Windows 第4版〈上〉』の「6.5.8 タイムスライス」

*2:より汎用的に書くなら,timeGetDevCaps で得られた最小分解能を指定するべきでしょう