ProcessorAffinityMask

PCがたまに0.5秒くらい固まるので原因を調べていたら、DPC latency問題ってのがあるらしい。
ネットワークのDPCが大量に発行されて固まるときには、レジストリキー
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NDIS\Parameters\
のProcessorAffinityMaskの値を変えると負荷が下がるケースがあるようだ。
というところまではいいのだが、これの値の意味がいまいち不明。

The 0x0 or 0xFFFFFFFF values are used to disable the ProcessorAffinityMask entry.

The processor load is not distributed across multiple processors on a computer that is running Windows Server 2003, Windows 2000 Server, or Windows NT 4.0

省略時解釈では、Windows NT 4.0 は対称割り込み分散を使用せず、ネットワーク・アダプターに関連付けられている DPC アクティビティーを関連するプロセッサーに割り当てます。
(snipped)
ProcessorAffinityMask の省略時値は x'ffffffff' です。複数のプロセッサー間でネットワーク DPC アクティビティーを平衡化するには、ProcessorAffinityMask を x'0' に設定してシステムをリブートします。

Tivoli Storage Manager Performance Tuning Guide

マルチプロセッサシステムの着信ネットワークトラフィックを処理する Windows の遅延割り込み要求のデフォルト DPC (Deferred Procedure Call) 処理は、パフォーマンスに悪い影響を与える可能性があります。実際には、DPC となる遅延割り込みは、あるプロセッサから別のプロセッサに再スケジュールされて、大幅なオーバーヘッドの増加をもたらします。このような DPC オーバーヘッド問題を防止するには、次のレジスタキーで ProcessorAffinityMask の値を 0 に設定します。

Sun ONE Directory Server インストールおよびチューニングガイド : 第 5 章 オペレーティングシステムのチューニング

KB892100には「0および0xFFFFFFFFはProcessorAffinityMaskエントリを無効にする。プロセッサ数に応じた設定値に変えろ」と書いてある。
二番目のIBMのページでは「0と0xFFFFFFFFはふるまいが違う」、三番目のSunのページでは「0にしろ」となっている。


似たような割り当てツールでIntFiltrというのがあるのだが、0および0xFFFFFFFF以外を指定したときのふるまいはIntFiltrのaffinityの指定値と同じではないかと思われる。それを踏まえて、もし上記の三つのページに書いてあることが全て正しいとするならば、ProcessorAffinityMaskに関わる動作は以下のような感じだと想像。

  1. エントリの初期値は0xFFFFFFFFである。
  2. 0xFFFFFFFF指定時、あるNICの処理でネットワークのDPCを発行すると、新しいDPCはNIC番号に対応するCPUに割り当てられる。
  3. 0指定時、あるNICの処理でネットワークのDPCを発行すると、新しいDPCは最も空いているCPUに割り当てられる。
  4. 0でも0xFFFFFFFFでもない値を指定したとき、あるNICの処理でネットワークのDPCを発行すると、新しいDPCはエントリで指定した値の各bitに対応するCPUのいずれかに割り当てられる。


KB892100の書き方で悩むのは「エントリが無効」ということの意味。「無効=既定値=0と0xFFFFFFFFは同じ動作」と解釈することもできるし、「0と0xFFFFFFFFの動作は違うのだが、エントリの目的である特定のCPUへのDPC割り当て制御という機能は無効」、と解釈できなくもない。KB892100の書き方だと
(A)0でもbitを立てた場合でも動作は同じだけど、指定した方が行儀がいい
(B)あるバージョン以降のWindowsでは、0は0xFFFFFFFFと同じ
のどちらなのかわからない。まあMSは値をセットしろと言っているので、そうした方が確実なのかな。


手元の環境ではWindows2000とXPの初期値は0xFFFFFFFFとなっていた。しかし上の仕様が正しいとすると初期値が0xFFFFFFFFなのは謎である。ふるいマルチプロセッサ環境だと別のCPUへのコンテキストスイッチが負担だから固定割り当てをデフォルトにしていた、というような事情だろうか?