web-dev-qa-db-ja.com

-jオプションを作成するために渡す最大数を決定する方法は?

できるだけ早くコンパイルしたい。図を行きます。 -jオプションに続く番号の選択を自動化したいと思います。プログラムでその値を選択するにはどうすればよいですか。シェルスクリプトで?

nprocの出力は、コンパイルに使用できるスレッドの数と同じですか?

make -j1make -j16

38
tarabyte

nprocは、使用可能なCPUコア/スレッドの数を示します 2ウェイSMTをサポートするクアッドコアCPUで8。

_-j_オプションを使用してmakeと並行して実行できるジョブの数は、いくつかの要因によって異なります。

  • 利用可能なメモリの量
  • makeジョブが使用するメモリの量
  • makeジョブがI/OまたはCPUにバインドされている範囲

make -j$(nproc)は適切な開始点ですが、使用可能なメモリを使い果たしてスラッシングを開始しない限り、通常はより高い値を使用できます。

本当に速いビルドの場合、十分なメモリがある場合は、tmpfsを使用することをお勧めします。これにより、ほとんどのジョブがCPUにバインドされ、make -j$(nproc)が可能な限り高速に動作します。

42
Stephen Kitt

残念ながら、同じビルドの異なる部分でも、ビルドされているもの、方法、その時点でシステムリソースのどれがボトルネックであるか、ビルドマシンで他に何が起こっているか、何が起こっているかによって、jファクター値の競合が最適になる場合があります。ネットワーク(分散ビルド手法を使用している場合)、ビルドに関係する多くのキャッシングシステムのステータス/場所/パフォーマンスなど.

100個の小さなCファイルをコンパイルする方が、1つの巨大なCファイルをコンパイルするよりも高速かもしれません。逆もまた同様です。非常に複雑な小さなコードの構築は、大量の単純な線形コードを構築するよりも遅くなる可能性があります。

ビルドのコンテキストも重要です-排他的で重複しないビルド用に微調整された専用サーバーでのビルド用に最適化されたjファクターを使用すると、同じ共有サーバー上で並行してビルドする開発者が使用すると非常に期待外れの結果が生じる可能性があります(そのようなビルドごとにさらに時間がかかる場合があります)シリアル化されている場合、またはハードウェア構成が異なるか、仮想化されているサーバーですべてを組み合わせた場合よりも時間がかかります。

ビルド仕様の正確さの側面もあります。非常に複雑なビルドでは、jファクターの増加または減少に伴って大きく変動する発生率で、断続的なビルドエラーを引き起こす競合状態が発生する可能性があります。

どんどん進むことができます。重要なのは、実際にyourビルドを実際に評価する必要があるということですj係数を最適化したい場合。 @Jeff Schallerのコメントが適用されます。最適なものが見つかるまで繰り返します。個人的に私はnproc値から始めて、上向きの試みがすぐに低下を示す場合にのみ、最初に上向きに、そして下向きに試します。

測定値のばらつきを把握するために、最初は同じコンテキストで同じビルドをいくつか測定することをお勧めします。高すぎると、最適化作業全体を危険にさらす可能性があります(20%のばらつきは完全にEclipseを10%改善します/ jファクター検索での読み取り値の低下)。

最後に、私見では、固定のj係数の代わりに(適応) jobserver がサポートされており、利用可能な場合に使用することをお勧めします-幅広いコンテキストで一貫してより優れたビルドパフォーマンスを提供します。

8
Dan Cornilescu

最も簡単な方法は、nprocを次のように使用することです。

make -j`nproc`

コマンドnprocは、マシンのコアの数を返します。ティックで囲むことにより、nprocコマンドが最初に実行され、数値が返され、その数値がmakeに渡されます。

Core-count + 1を実行するとコンパイル時間が短縮されるという、事例的な経験があるかもしれません。これは、I/Oの遅延、その他のリソースの遅延、リソース制約のその他の可用性などの要因と関係があります。

nproc+1でこれを行うには、次を試してください:

make -j$((`nproc`+1))
8
010110110101

仮想CPUの数と同じ数の並列ワーカーを使用するようにmakeコマンドを記述したい場合は、以下を使用することをお勧めします。

nproc | xargs -I % make -j%

スタンドアロンコマンドとして、またはRUN内のDockerfileディレクティブとして記述できます(Dockerはネストされたコマンドをサポートしていないため)。

0
Maksym Ganenko
lscpu | grep "^CPU(" | awk '{print $2}'

これにより、CPUコアの数がわかります。

0
Lynne