Windowsでプログラムの実行に使用するCPUを限定させる(プロセッサアフィニティマスクを設定する):Tech TIPS
マルチプロセッサ・システム上で使用すると不具合を起こすアプリケーションがあるが、このような場合は、実行に使用するCPUを1つだけに限定させるとよい。アプリケーションに割り当てるCPUを限定させるには、タスク・マネージャで「関係」を設定する。実行ファイルにアフィニティ・マスクを設定してもよい。
対象OS:Windows 2000/Windows XP/Windows Server 2003/Windows Vista
解説
ハイパー・スレッディング(Hyper Threading:HT)やマルチコア、マルチプロセッサ・システムなど、複数のスレッドを、(擬似的ではなく、本当に)同時に実行させることのできるシステムが増えている。Windows OSはマルチプロセッサ・システムに対応しており、これらのプロセッサが装備されていると、複数のスレッドを各CPU(本TIPSでいう「CPU」とは、1つのスレッドを実行する処理エンジンのことを指すものとする。HTなら2 CPU相当と数える)に自動的に割り振り、効率的に処理を実行する。
マルチプロセッサ・システム上でのWindows Server 2003 R2の例
このシステムには2つのCPU(実際はハイパー・スレッディング対応コア)が搭載されているので、タスク・マネージャでは2つのコアそれぞれの状態が別々に表示される。
(1)1つ目のCPUの使用率。
(2)2つ目のCPUの使用率。
非常に便利で有用な機能であるが、場合によっては問題が発生することがある。マルチ・プロセッサ対応していない古いアプリケーション(もしくは対応やテストが不十分なアプリケーション)などでは、1つのリソース(プログラム中で利用するデータなど)を同時に複数のスレッドから操作しようとして不整合を起こしたりする可能性があるからだ。
このような場合は、(アプリケーションを改修するのが本来の方法であるが、取り急ぎ対処するなら)、アプリケーションの実行に使用するCPUを1つだけに限定させるとよい。ちょうどシングルCPUシステム上で実行するのと同じ状態にするのである。これならスレッド間でのリソース・アクセスの競合などが起こらず、正しく動作するようなるだろう。未使用のCPUは、ほかのプロセスやOSなどで利用されるので、システム全体のパフォーマンスが損なわれることもない。
また、マルチスレッド対応アプリケーションであっても、全CPUの処理時間を占有してしまうような重いプログラムの場合には、このCPUを限定させる機能を利用するとよい。特定のアプリケーションだけでCPUが占有されることがなくなり、ほかの処理(特にGUI操作など)がスムーズに行えるようになる。
本TIPSでは、ある特定のアプリケーションにおいて、実行に使用するCPUを限定させる方法について解説する。システム起動時から(OS全体で)1つのCPUだけしか使用させない方法については、TIPS「システム全体で使用するCPU数を限定させる」を参照していただきたい。
なおアプリケーションごとに、そのアプリケーションがどのCPUを使用するかという関係付けのことを「アフィニティ(affinity、関係とか有縁性などという意味)」といい、日本語Windows OSでは「関係」という用語で呼んでいる。またアプリケーションとCPUの対応状況をアフィニティ・マスクと呼ぶ。
操作方法
●タスク・マネージャでの操作
アプリケーションで使用するCPUを限定させる一番簡単な方法は、実行中のアプリケーションをタスク・マネージャで選択し、[関係の設定]を実行する。
アフィニティ・マスクの設定
アフィニティ・マスクを設定したいプロセスを選び(システム・プロセスやサービスなどは設定不可)、[関係の設定]を選ぶ。ただしシングルCPUシステムではこのメニュー項目は表示されない。
(1)設定したいプロセスを右クリックする。
(2)これを選択する。
(2)を選ぶと次のようなダイアログが表示されるので、実行を許可したいCPUのチェック・ボックスだけをオンにし、不要なCPUに対してはオフにする。
アフィニティ・マスクの設定
システムに装備されているCPUの数だけチェック・ボックスが並び、そのプロセスで利用可能なCPUのチェック・ボックスがオンになっている。CPUの使用を限定させたい場合は、特定のCPUのチェック・ボックスだけをオンにし、実行させたくないCPUはオフにする。デフォルトでは、全CPUのチェック・ボックスがオンになっている。
(1) 1つ目のCPUでの実行を許可するかどうかの設定。
(2)2つ目のCPUでの実行を許可するかどうかの設定。
以上の設定により、ある特定のアプリケーション(の中のスレッド)が、指定されたCPUでしか実行されなくなる。リソースの競合問題などを起こしているアプリケーションならば、実行するCPUを1つだけに限定する(と解決できる可能性がある)。全CPUの処理時間を消費するのを抑えたいのなら、1つだけオフにし、残りのCPUはそのままオンにしておく。
なおこの設定は、シングルスレッド対応のアプリケーションをマルチスレッド対応にするものではない。アプリケーションがシングルスレッドでしか動作していなければ、いくら複数のCPUを割り当てても使用されるCPUは1つだけである。
●実行ファイルに対するアフィニティ・マスクの設定
以上の操作は、すでに起動しているアプリケーションに対する操作方法であるが、場合によってはこれでは不十分なことがある。ユーザーがタスク・マネージャで操作する前に、マルチスレッドによる不具合が発生していれば防ぐことはできないし、いちいち手動で操作しなければならないからだ。
このような場合は、あらかじめアプリケーションの実行ファイルに対して、アフィニティ・マスクを設定しておくとよい。これならば起動時から正しく使用するCPUが限定できる。
.EXE実行ファイルに対してアフィニティ・マスクを設定するには、IMAGECFG.EXEというツールが利用できる。これはWindows NT 4.0のサポート・ツール、もしくはWindows 2000 Resource Kitとして提供されていたツールである。ただし古いツールなので、最新のOSで動作するかどうかは不明である。手元では、Windows XP上では動作したしたが、Windows Server 2003上ではエラーとなった(Windows XP上で設定した.exeファイルでも、Windows Server 2003上で利用可能)。
このツールに「-a 1」というふうにオプションを与えると、アフィニティ・マスクを設定できる(10進数の場合はそのまま、16進数の場合は先頭に0xを付ける)。アフィニティ・マスクは2進数のbit配列として解釈され、最下位bitがCPU 0(10進数で1に相当)、次のbitがCPU 1(10進数で2に相当)、その次のbitがCPU 2(10進数で4に相当)、……となっている。実行を許可したいCPUのbitを1にして数値で指定する。
C:\>imagecfg -a 1 MySampApp.exe
MySampApp.exe contains no configuration information
MySampApp.exe contains a Subsystem Version of 4.0
MySampApp.exe updated with the following configuration information:
Process Affinity Mask: 00000001
C:\>
これは、CPU 0でのみ許可する場合の例である。起動後にタスク・マネージャで確認すると、指定されたCPUのチェック・ボックスがオンになっているはずである。
●Windows VistaではStartコマンドでも指定可能
Windows Vistaでは、コマンド・プロンプトからSTARTコマンドで起動する際にアフィニティ・マスクを指定できるようになっている(Windows XP以前のOSでは使用不可)。
C:\>start /affinity 1 MySampApp.exe
「/affinity」に続いて、アフィニティ・マスクの値を16進数(先頭の0xは付けなくても常に16進数として解釈される)を指定する。
●プログラムではSetProcessAffinityMask APIで対応する
以上の方法は、すべてプログラムの作成後にアフィニティ・マスクを設定しているが、プログラム自身で使用するCPUを判断し、切り替えるには、SetProcessAffinityMaskというAPIなどを利用する。
■この記事と関連性の高い別の記事
- 負荷の大きいプロセスを特定する方法(TIPS)
- システム全体で使用するCPU数を限定させる(TIPS)
- Windows OSでよく見かける重いプロセス、ベスト10(TIPS)
- 仮想マシンの実行優先度を調整する(Virtual Server 2005編)(TIPS)
- カーネル・モードとユーザー・モードの負荷状況を簡単に見分ける方法(TIPS)
Copyright© Digital Advantage Corp. All Rights Reserved.