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等のマルチコアでは試していないので、上手くいくかどうかは判らない(試して上手くいった方は是非、教えて頂きたい)