複数のコアを使用してg ++でコンパイルする


174

簡単な質問:大規模なプロジェクトをより速くコンパイルするためにg ++がそれ自体の複数のインスタンスを生成できるようにするコンパイラフラグとは何ですか(たとえば、マルチコアCPUで一度に4つのソースファイル)。


それは本当に役に立ちますか?すべてのコンパイルジョブは、CPUバウンドではなくI / Oバウンドです。
Brian Knoblauch、

5
それらがI / Oバウンドであっても、CPUの重いビットが発生しているときはI / O負荷を高く保つことができ(g ++インスタンスが1つだけある場合は沈静化します)、スケジューラにもっと選択肢がある場合はI / O効率を上げることができます次にディスクから何を読み取るか。私の経験では、make -jほとんどの場合、賢明な使用はある程度の改善につながります。
フレキソ

1
@BrianKnoblauchしかし、私のマシン(実際のマシンまたはVirtualBox)では、CPUがバインドされているため、コンパイル時に「top」コマンドを使用してCPUがビジーであることがわかりました。
大宝剑

1
I / Oバウンドであっても、gccのフラグ「-pipe」を使用して痛みを軽減できます。
大宝剑

これはグーグルで見たばかりです:gcc.gnu.org/onlinedocs/libstdc++
ジムマイケルズ

回答:


240

これはmakeで行うことができます-gnu makeでは-jフラグです(これはユニプロセッサーマシンでも役立ちます)。

たとえば、makeから4つの並列ジョブが必要な場合:

make -j 4

パイプでgccを実行することもできます

gcc -pipe

これにより、コンパイル段階がパイプライン化され、コアをビジー状態に保つのにも役立ちます。

利用可能な追加のマシンもある場合は、distccをチェックアウトすることもできます。これにより、ファームコンパイルもそれらにコンパイルされます。


36
あなたは-j数があなたの持っているコアの数の1.5倍でなければなりません。
Mark Beckwith、

2
ありがとう。CFLAGS / CPPFLAGS / CXXFLAGSを介して "-j#"をgccに渡そうとし続けました。「-j#」がGNU makeのパラメーターであること(GCCのパラメーターではないこと)を忘れていました。
chriv 2012

33
GNU Makeの-jオプションがCPUコアの数の1.5倍になる必要があるのはなぜですか?
bitek

28
1.5注意のための数であるI / Oバインドの問題を。経験則です。ジョブの約1/3がI / Oを待機するため、残りのジョブは使用可能なコアを使用します。コアよりも大きい数の方が優れており、2倍にもなる可能性があります。参照:Gnuの-j議論
アートレスノイズ2013

4
@JimMichaelsプロジェクト内で依存関係が正しく設定されていないため(依存関係の準備がまだ整っていなくてもターゲットがビルドを開始する)、結果としてシーケンシャルビルドのみが成功する可能性があります。
アントニオ

42

そのようなフラグはなく、各ツールに1つの機能だけを実行させ、それを適切に実行させるというUnixの哲学に反するものがあります。コンパイラー・プロセスの生成は、概念的にはビルド・システムの仕事です。あなたがおそらく探しているのは、GNU makeの-j(jobs)フラグです。

make -j4

または、pmakeまたは同様の並列makeシステムを使用できます。



3
「Unixのペダナリーは役に立たない」当時はペダナリーではなかったのはいいことだ、匿名の編集者。ロールバックしました。レビュアーはあなたがしていることにもっと注意を払ってください。
オービットのライトネスレース

12

人々は言及しましたmakebjam、同様の概念もサポートしています。を使用bjam -jxすると、bjamにx同時コマンドまでビルドするように指示します。

WindowsとLinuxで同じビルドスクリプトを使用し、このオプションを使用すると、両方のプラットフォームでのビルド時間が半分になります。いいね。


9

makeあなたのためにこれを行います。マニュアルページの-jおよび-lスイッチを調べてください。g++並列化はできないと思います。


-lオプションを言及するための+1 (以前のすべてのジョブが終了しない限り、新しいジョブを開始しません)。それ以外の場合は、一部のコンパイルがまだ進行中であるため、すべてのオブジェクトファイルがビルドされずにリンカージョブが開始するため、リンカージョブは失敗します。
NGI 2018

8

makeを使用している場合は、を発行し-jます。からman make

  -j [jobs], --jobs[=jobs]
       Specifies the number of jobs (commands) to run simultaneously.  
       If there is more than one -j option, the last one is effective.
       If the -j option is given without an argument, make will not limit the
       number of jobs that can run simultaneously.

そして最も注目すべきは、スクリプトを作成したり、使用可能なコアの数を特定したりする場合(環境によって異なり、多くの環境で実行すると、状況が大きく変化する可能性があります)、ユビキタスPython関数を使用できますcpu_count()

https://docs.python.org/3/library/multiprocessing.html#multiprocessing.cpu_count

このような:

make -j $(python3 -c 'import multiprocessing as mp; print(int(mp.cpu_count() * 1.5))')

1.5上記のコメントでなぜ私がユーザーartless-noiseを引用するのかと尋ねている場合:

1.5の数値は、指摘されたI / Oバウンドの問題が原因です。経験則です。ジョブの約1/3がI / Oを待機するため、残りのジョブは使用可能なコアを使用します。コアよりも大きい数の方が優れており、2倍にもなる可能性があります。


5
ほとんどのLinuxユーザーは、おそらく短いを好むだろう。make -j`nproc` nprocGNUのCoreutilsに。
Ciro Santilli郝海东冠状病六四事件法轮功

SSDを使用している場合、I / Oはそれほど問題にはなりません。上記のCiroのコメントを基に、これを行うことができます:( make -j $(( $(nproc) + 1 ))私がいる場所にスペースを入れてください)。
Ed K

Pythonを使用した素晴らしい提案nprocです。たとえば、manylinux1コンテナー内で使用できないシステムでは、yum update/の実行を回避することで追加の時間を節約できますyum install
hoefling


3

g ++についてはわかりませんが、GNU Makeを使用している場合は、「make -j N」(Nはmakeが作成できるスレッドの数)により、makeで複数のg ++​​ジョブを同時に実行できます(非常に長い間)ファイルは相互に依存しないため)。


2
Nはスレッドの数ではありません!多くの人はそれを誤解してい-j Nますが、スレッドではなく一度にいくつのプロセスを生成するかを教えています。それがMS cl -MT(実際にはマルチスレッド)ほどパフォーマンスが良くない理由です。
Sebi2020

2

GNUパラレル

私は合成コンパイルのベンチマークを作成していて、Makefileを作成する気にならなかったので、次を使用しました。

sudo apt-get install parallel
ls | grep -E '\.c$' | parallel -t --will-cite "gcc -c -o '{.}.o' '{}'"

説明:

  • {.} 入力引数を取り、その拡張子を削除します
  • -t 実行中のコマンドを出力して、進捗状況を知らせます
  • --will-cite ソフトウェアを使用して結果を公開する場合、ソフトウェアを引用する要求を削除します...

parallel 私はタイムスタンプチェックを自分で行うことさえできるほど便利です:

ls | grep -E '\.c$' | parallel -t --will-cite "\
  if ! [ -f '{.}.o' ] || [ '{}' -nt '{.}.o' ]; then
    gcc -c -o '{.}.o' '{}'
  fi
"

xargs -Pジョブを並行して実行することもできますが、拡張機能を操作したり、複数のコマンドを実行したりするのは少し不便です。xargsを使用した複数のコマンドの呼び出し

並列リンクが尋ねられました:gccはリンク時に複数のコアを使用できますか?

TODO:コンパイルを行列の乗算に削減できることをどこかで読んだので、大きなファイルの単一ファイルのコンパイルを高速化することも可能かもしれません。しかし、私は今、参照を見つけることができません。

Ubuntu 18.10でテスト済み。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.