/MP (複数のプロセスを使用したビルド)
更新 : 2007 年 11 月
/MP オプションを使用すると、コマンド ラインでソース ファイルをコンパイルする合計時間を短縮することができます。/MP オプションを使用することにより、コンパイラは自身の 1 つ以上のコピーを、それぞれ別個のプロセスで作成します。その後、それらのコピーはソース ファイルを同時にコンパイルします。結果として、ソース ファイルのビルドにかかる合計時間を大幅に短縮することができます。
/MP[processMax]
引数
processMax
(省略可能) コンパイラが作成できるプロセスの最大数。引数 processMax は 1 ~ 65536 の範囲にする必要があります。そうしないと、コンパイラは警告メッセージ D9014 を発行し、引数 processMax を無視して、プロセスの最大数が 1 であると見なします。
引数 processMax を省略すると、コンパイラはコンピュータ上の有効プロセッサの数をオペレーティング システムから取得し、プロセッサごとに 1 プロセスを作成します。
解説
多数のファイルをコンパイルする場合、/MP コンパイラ オプションはビルド時間を大幅に短縮させることができます。ビルド時間を改善するために、コンパイラは自身のコピーを最大 processMax 個まで作成し、その後そのコピーを使用してソース ファイルを同時にコンパイルします。/MP オプションはコンパイルに適用されますが、リンクまたはリンク時のコード生成には適用されません。既定では /MP オプションはオフになっています。
ビルド時間の改善は、コンピュータ上のプロセッサの数、コンパイルするファイルの数、およびシステム リソース (たとえば入出力の容量) が使用可能かどうかによって異なります。/MP オプションを試して、特定のプロジェクトのビルドの最良の設定を決定してください。決定の参考となるアドバイスについては、「ガイドライン」を参照してください。
互換性のないオプションおよび言語機能
/MP オプションは一部のコンパイラ オプションおよび言語機能と互換性がありません。/MP オプションと互換性がないコンパイラ オプションを使用すると、コンパイラは警告 D9030 を発行し、/MP オプションを無視します。互換性のない言語機能を使用すると、コンパイラはエラー C2813 を発行し、現在のコンパイラの警告レベル オプションに応じて終了または続行します。
メモ : |
---|
ほとんどのオプションは互換性がありません。これらのオプションが許可されると、同時に実行されるコンパイラがコンソールまたは特定のファイルに対して出力を同時に書き込むことになるためです。その結果、出力が混じり合って、悪影響が発生します。場合によっては、オプションの組み合わせによってパフォーマンスが低下することもあります。 |
/MP オプションと互換性がないコンパイラ オプションおよび言語機能を次の表に示します。
オプションまたは言語機能 |
説明 |
---|---|
#import プリプロセッサ ディレクティブ |
タイプ ライブラリの型を C++ クラスに変換し、そのクラスをヘッダー ファイルに書き込みます。 |
プリプロセッサ出力を標準出力 (stdout) にコピーします。 |
|
インクリメンタル リビルドを有効にします。 |
|
インクルード ファイルのリストを標準エラー (stderr) に書き込みます。 |
|
プリコンパイル済みヘッダー ファイルを作成します。 |
診断メッセージ
/MP オプションと互換性がないオプションまたは言語機能を指定すると、診断メッセージを受け取ります。このようなメッセージおよびコンパイラの動作を次の表に示します。
診断メッセージ |
説明 |
コンパイラの動作 |
---|---|---|
#import ディレクティブは /MP オプションと互換性がありません。 |
コンパイラの警告レベル オプションが継続を指定しない場合、コンパイルは終了します。 |
|
引数 processMax に無効な値が指定されています。 |
コンパイラは無効な値を無視し、値が 1 であると見なします。 |
|
指定したオプションは /MP と互換性がありません。 |
コンパイラは /MP オプションを無視します。 |
ガイドライン
パフォーマンスの計測
パフォーマンスの計測には合計ビルド時間を使用します。物理クロックを使ってビルド時間を計測したり、ビルドの開始時刻と停止時刻の差を計算するソフトウェアを使用したりすることができます。コンピュータに複数のプロセッサがある場合は、ソフトウェアによる時間の計測よりも物理クロックを使った方が正確な結果が得られる可能性があります。
有効プロセッサ
コンピュータには、物理プロセッサごとに 1 つ以上の仮想プロセッサを備えることができます。そのような仮想プロセッサは、有効プロセッサとも呼ばれます。各物理プロセッサには 1 つ以上のコアを備えることができ、オペレーティング システムでコアのハイパースレッドが有効になっている場合は、それぞれのコアが 2 つの仮想プロセッサのように見えます。
たとえば、コンピュータが 1 つの物理プロセッサを持ち、そのプロセッサに 1 つのコアがあり、ハイパースレッドが無効になっている場合、そのコンピュータの有効プロセッサの数は 1 です。一方、コンピュータに 2 つの物理プロセッサがあり、さらにそれぞれのプロセッサに 2 つのコアがあり、すべてのコアのハイパースレッドが有効な場合、そのコンピュータの有効プロセッサ数は 8 です。つまり、(8 つの有効プロセッサ) = (2 つの物理プロセッサ) x (1 つの物理プロセッサにつき 2 つのコア) x (ハイパースレッドにより 1 つのコアにつき 2 つの有効プロセッサ) ということです。
/MP オプションの引数 processMax を省略すると、コンパイラは有効プロセッサ数をオペレーティング システムから取得し、有効プロセッサごとに 1 つのプロセスを作成します。ただし、コンパイラはどのプロセスが特定のプロセッサで実行するかを保証できません。その決定はオペレーティング システムが行います。
プロセスの数
コンパイラは、ソース ファイルをコンパイルするために使用するプロセスの数を計算します。その値は、コマンド ラインで指定したソース ファイル数と /MP オプションを使用して明示的または暗黙的に指定したプロセス数のうちの小さい方です。/MP オプションの引数 processMax を指定すると、プロセスの最大数を明示的に設定することができます。また、引数 processMax を省略すると、既定値を使用できます。この既定値は、コンピュータの有効プロセッサ数と同じです。
たとえば、次のコマンド ラインを指定したとします。
cl /MP7 a.cpp b.cpp c.cpp d.cpp e.cpp
この場合、コンパイラは 5 つのプロセスを使用します。その数はソース ファイル数の 5 と最大プロセス数の 7 の小さい方の値だからです。今度は、コンピュータに 2 つの有効プロセッサがあり、次のコマンド ラインを指定したとします。
cl /MP a.cpp b.cpp c.cpp
この場合、オペレーティング システムは 2 つのプロセッサがあると報告するので、コンパイラはその計算でプロセス数として 2 を使用します。その結果、コンパイラは 2 つのプロセスを使用してビルドを実行します。ソース ファイル数の 3 より小さい、プロセス数の 2 が使用されるからです。
ソース ファイルとビルドの順序
ソース ファイルは、コマンド ラインに指定した順序と同じ順序でコンパイルされない場合があります。コンパイラは、コンパイラのコピーを含む一連のプロセスを作成しますが、各プロセスの実行タイミングのスケジュールはオペレーティング システムが行います。したがって、ソース ファイルのコンパイル順序は保証されません。
ソース ファイルは、プロセスがソース ファイルをコンパイルするために使用可能なときにコンパイルされます。プロセスより多くのファイルが存在する場合、使用できるプロセスによって最初のファイルのセットがコンパイルされます。残りのファイルは、プロセスが前のファイルの処理を完了し、残りのファイルの 1 つを処理できるようになったときに処理されます。
同じソース ファイルをコマンド ラインで複数回指定しないでください。たとえば、プロジェクトの依存情報に基づいた makefile がツールによって自動的に作成される場合などに、複数回指定される可能性があります。/MP オプションを指定しない場合、コンパイラはファイルのリストを順番に処理し、ファイルが繰り返されてもそのたびに再コンパイルします。しかし、/MP オプションを指定すると、異なるコンパイラが同じファイルを同時にコンパイルする可能性があります。その結果、異なるコンパイラが同じ出力ファイルに同時に書き込もうとします。1 つのコンパイラが出力ファイルへの排他書き込みアクセスを取得して成功し、それ以外のコンパイラはファイル アクセス エラーによって失敗します。
タイプ ライブラリの使用 (#import)
コンパイラは #import ディレクティブと /MP スイッチの併用をサポートしていません。可能な場合は、次の手順に従ってこの問題を回避してください。
さまざまなソース ファイルの #import ディレクティブすべてを 1 つまたはいくつかのファイルに移動し、それらのファイルを /MP オプションを使用せずにコンパイルします。これにより、一連のヘッダー ファイルが生成されます。
残りのソース ファイルに、生成されたヘッダーを指定した #include ディレクティブを挿入し、/MP オプションを使用して残りのソース ファイルをコンパイルします。
Visual Studio プロジェクトの設定
VCBUILD.exe ツール
Visual Studio は、VCBUILD.exe ツールを使用してソリューションやプロジェクトをビルドします。VCBUILD.exe ツールは複数のプロジェクトを同時にビルドすることができます。また、/MP コンパイラ オプションを使うと複数のコンパイル単位を同時にビルドすることができます。アプリケーションで適切な場合は、/MP および VCBuild のいずれか、またはその両方を使用してソリューションのビルド時間を改善してください。
ソリューションのビルド時間は、ビルドを実行するプロセスの数にある程度依存します。VCBUILD.exe ツールの /M オプションは、同時にビルドするプロジェクトの最大数を指定します。同様に、/MP オプションの引数 processMax も、同時にビルドするコンパイル単位の最大数を指定します。/M オプションで P プロジェクトを指定し、/MP オプションで C プロセスを指定すると、最大 PxC のプロセスが同時に実行されます。
VCBuild や /MP テクノロジを使用するかどうかを決定するためのガイドラインを次に示します。
プロジェクトが多数あり、それぞれのプロジェクトのファイル数が少ない場合は、VCBuild ツールを使用します。
プロジェクトの数が少なく、それぞれのプロジェクトのファイル数が多い場合は、/MP オプションを使用します。
プロジェクトの数とプロジェクトごとのファイルの数のバランスが取れている場合は、VCBuild と /MP の両方を使用します。最初は、/M オプションをビルドするプロジェクトの数に設定し、/MP オプションをコンピュータ上のプロセッサの数に設定します。パフォーマンスを計測し、最良の結果が得られるように設定を調整します。合計ビルド時間に満足できるようになるまで、このサイクルを繰り返します。
/Gm コンパイラ オプション
既定で、プロジェクト ビルドは、デバッグ ビルドで /Gm コンパイラ オプション (インクリメンタル ビルド) を有効にし、リリース ビルドでこれを無効にします。そのため、/MP コンパイラ オプションはデバッグ ビルドで既定の /Gm コンパイラ オプションと競合するので、自動的に無効になります。