私は4つのプロセッサを使用しており、プロセッサの空腹なアプリケーションをコンパイルしています。OpenCVでは-j4スイッチでmakeを使用することをお勧めします。
あなたが言うように-j
フラグは、指定された量の「スレッド」を生成できることをmakeに伝えます。理想的には、各スレッドは独自のコア/ CPUで実行されるため、マルチコア/ CPU環境が最大限に活用されます。
make
自体はソースファイルをコンパイルしません。これは、コンパイラー(gcc)によって行われます。 Makefile(make
の入力)にはターゲットのセットが含まれています。各ターゲットには、(他のターゲットに対する)依存関係のセットと、ターゲットの構築方法のルールがあります。 make
はMakefileを読み取り、すべてのターゲット、依存関係、ビルドルールを管理します。ソースファイルのコンパイルに加えて、make
を使用して、シェルコマンドで記述できるタスクを実行できます。
許可されるスレッドの数が多すぎると、各スレッドを独自のコアでスケジュールすることはできません。すべてのスレッドを実行するには、追加のスケジューリング(コンテキスト)スイッチが必要です。この追加のリソース使用により、明らかにパフォーマンスが低下します。
経験則は複数ありますが、合計金額の設定は<number of cores> + 1
が最も一般的です。この背後にある考え方は、すべてのコアが独自のスレッドを持ち、ターゲットを処理し、次にビルドされる管理スレッドが1つ追加されるということです。
上記の答えはほとんどすべて正しいです。ただし、詳細は少し誤解を招く可能性があります。たとえば、「スレッドの管理」のために追加のジョブを追加する必要はありません(注:make
は実際にはマルチスレッドではありません)。 make
は、-j
ですので、上記のホイヘンスが言うように、-j5
4つ以上のmakeではなく、5つのコンパイルジョブが実行されます。
ほとんどの人が[コア数] + [パディング]を使用する理由は、make
または必要なものとは関係なく、コンパイラの性質と関係があります。コンパイラは実際には非常に複雑なテキスト翻訳ツールです。ある形式のテキストを読み取り、別の形式の「テキスト」(バイナリ)に変換します。これの多くは(特に、C++のように言語がより複雑になるにつれて)、大量のCPUを必要とします。ただし、大量のディスクI/Oも必要です。ディスクI/Oは遅いため、1つのコンパイラがディスクからのデータを待機している間、カーネルは他のジョブの実行をスケジュールします。そのため、複数のコアコンパイルを同時に実行できるので便利です。
取得できる正確なサイズ-j
リターンの減少が見られる前(ビルドは実際には遅くなり、ある時点で、より多くの-j
)は、ハードウェア、実行しているビルドの種類などに完全に依存します。確実に知る唯一の方法は、実験です。
ただし、[コアの数] + [少数]は通常、適切な近似値です。
スレッドごとに1つのCPUと1つのマネージャー/ローダー。ディスク操作を行うスレッドは、CPUの観点からは技術的にほとんどアイドル状態なので、コアの合計数に1を追加します。
CPUがハイパースレッディングを使用している場合、各コアを2つのコアとして安全にカウントし、スレッド数を2倍にすることができます。
-j
オプションは、アプリケーションのビルドを高速化するためにのみ使用され、ビルドのためにmake
が生成できるジョブの数を決定します。 -j<nb core>
またはそれ以上の-j<nb-core * 1.5>
を設定して、コンパイルを並行して実行できるようにすることができます。
コンパイルされたコードには影響しません。
4コアシステムの場合、make -j6
を試すことができます。 makeが並列ビルドを実行できる場合、最大6つの同時コンパイルプロセス(gccへの6つの呼び出しなど)を起動します。