簡単な質問:大規模プロジェクトをより速くコンパイルするために、g ++がそれ自体の複数のインスタンスを生成できるようにするコンパイラフラグとは何ですか(たとえば、マルチコアCPUの場合は一度に4つのソースファイル)。
Makeでこれを行うことができます-gnu makeで-jフラグになります(これは、ユニプロセッサマシンでも役立ちます)。
たとえば、makeから4つの並列ジョブが必要な場合:
make -j 4
パイプでgccを実行することもできます
gcc -pipe
これにより、コンパイルステージがパイプライン処理され、コアをビジー状態に保つのに役立ちます。
追加のマシンも利用できる場合は、 distcc をチェックアウトすると、ファームもコンパイルされます。
そのようなフラグはなく、各ツールが1つの機能だけを実行し、それを適切に実行するというUnixの哲学に反するものがあります。コンパイラプロセスの生成は、概念的にはビルドシステムの仕事です。おそらく探しているのは、GNU makeの-j(ジョブ)フラグです。
make -j4
または、pmakeまたは同様の並列makeシステムを使用できます。
人々はmake
に言及していますが、 bjam
も同様の概念をサポートしています。 bjam -jx
を使用すると、bjamはx
個の同時コマンドを作成します。
WindowsとLinuxで同じビルドスクリプトを使用し、このオプションを使用すると、両方のプラットフォームでビルド時間が半分になります。いいね.
make
がこれを行います。 manページで-j
および-l
スイッチを調べます。 g++
は並列化できるとは思わない。
distccは、現在のマシンだけでなく、distccがインストールされているファーム内の他のマシンでもコンパイルを配布するために使用できます。
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倍まで高くすることもできます。
G ++についてはわかりませんが、GNU Makeを使用している場合、「make -j N」(Nはmakeが作成できるスレッドの数)により、makeで複数のg ++ジョブを実行できます。同時に(ファイルが相互に依存しない限り)。
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。でテスト済み。