web-dev-qa-db-ja.com

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

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

164
bsofman

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

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

make -j 4

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

gcc -pipe

これにより、コンパイルステージがパイプライン処理され、コアをビジー状態に保つのに役立ちます。

追加のマシンも利用できる場合は、 distcc をチェックアウトすると、ファームもコンパイルされます。

226
frankodwyer

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

make -j4

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

40

人々はmakeに言及していますが、 bjam も同様の概念をサポートしています。 bjam -jxを使用すると、bjamはx個の同時コマンドを作成します。

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

11
MattyT

makeがこれを行います。 manページで-jおよび-lスイッチを調べます。 g++は並列化できるとは思わない。

8
rmeador

distccは、現在のマシンだけでなく、distccがインストールされているファーム内の他のマシンでもコンパイルを配布するために使用できます。

5
Jason

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倍まで高くすることもできます。

4
Havok

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

2
Andy

GNU parallel

私は 合成コンパイルのベンチマーク を作成していたので、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。でテスト済み。