JVMが特定のCPU(だけ)を使うように設定する

なんとWindowsNT以降のResourceKit等に添付されているImageCFG.exeでCPU affinityの設定を行えるようだ。(イメージヘッダの書き換えなので、設定というよりパッチ当てと同等だが)

C:\Users\Kazz>imagecfg
usage: IMAGECFG [switches] image-names...
              [-?] display this message
              [-s path to symbol files]
              [-v MajorVersion.MinorVersion]
              [-w Win32 GetVersion return value in hex]
              [-a Process Affinity mask value in hex]
              [-u Marks image as uniprocessor only]
              [-r run with restricted working set]
              [-b BuildNumber]
              [-g bitsToClear bitsToSet]
              [-o default critical section timeout
              [-d decommit thresholds]
              [-m maximum allocation size]
              [-t VirtualAlloc threshold]
              [-p process heap flags]

たとえば、1プロセッサのみ使用可能とする場合であれば

imagecfg -u hogehoge.exe

であり、任意のCPUのaffinityを設定したいのであれば

imagecfg -a XXX hogehoge.exe

を実行してAffinity Maskを設定できる。その後のhogehoge.ezeは指定したCPUしか使用しなくなる。

XXXはCPUを表したビットマスクのHEX指定であり、それぞれ

0x1 (00000001) = CPU0 (一基目の最初の論理/物理CPUだけを使用する)
0x2 (00000010) = CPU1 (二基目の)
0x4 (00000100) = CPU2 (三基目の)
0x6 (00000110) = CPU1 or CPU2 (二基目と三基目の)
0xE (00001110) = CPU1 or CPU2 or CPU3(二基目と三基目、四基目)

と指定することができる。
私の場合、mAgicTV5が使っているCPU0だけは対象から外したいので、例えばeclipseのAffinityは

imagecfg -a 0xe eclipse.exe

と指定してやれば、eclipse及びそこから起動されるJVMはCPU0以外を使用する訳だ。

なお、ImageCFGはWin32バイナリのイメージヘッダを書き換えるアプリケーションなので、念のためバイナリのバックアップはとっておくことをお勧めする。
追記:
ImageCFGのProcess Affinityに関しては正式なドキュメントを探すことができなかった。undocumentedな機能なのかもしれない。

追記:
ImageCFGではないが、同じと思われるAffinity Maskの説明だけは少しだけ記述があった。
SQL Server 2000 オフィシャル マニュアル/ 第 36 章 ‐ 一般的なパフォーマンスの問題の解決 - 36.4.1 affinity mask オプション

追記:
私がこの設定で上手く動作したのはCPUをIntel Xeon(Prestonia)×2 HyperThreading on、O/SはWindows Vistaの環境だ(従って認識される論理CPUは四基)。最近のCoreDuo等のマルチコアでは試していないので、上手くいくかどうかは判らない(試して上手くいった方は是非、教えて頂きたい)