複数のコアを使用した g++ でのコンパイル
-
03-07-2019 - |
質問
簡単な質問:大規模なプロジェクトをより速くコンパイルするために、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
あなたの代わりにこれを行います。を調査してください -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パラレル
合成コンパイルのベンチマークを作成していましたが、できませんでしたMakefileを書くことに煩わされないので、私は使用しました:
sudo apt-get install parallel
ls | grep -E '\.c
説明:
-
{。}
は入力引数を取り、その拡張子を削除します
-
-t
は実行中のコマンドを出力し、進行状況を把握します
-
-will-cite
は、ソフトウェアを使用して結果を公開する場合にソフトウェアを引用する要求を削除します...
parallel
はとても便利なので、自分でタイムスタンプをチェックすることさえできます:
ls | grep -E '\.c
xargs -P
はジョブを並行して実行することもできますが、拡張機能の操作やそれを使用して複数のコマンドを実行するのは少し不便です: xargsを介した複数のコマンドの呼び出し
並列リンクは次の場所で尋ねられました: gccはリンク時に複数のコアを使用できますか?
TODO:コンパイルを行列の乗算に減らすことができることをどこかで読んだと思うので、大きなファイルの単一ファイルのコンパイルを高速化することもできます。しかし、私は今参照を見つけることができません。
Ubuntu 18.10。でテスト済み
| parallel -t --will-cite "gcc -c -o '{.}.o' '{}'"
説明:
-
{。}
は入力引数を取り、その拡張子を削除します
-
-t
は実行中のコマンドを出力し、進行状況を把握します
-
-will-cite
は、ソフトウェアを使用して結果を公開する場合にソフトウェアを引用する要求を削除します...
parallel
はとても便利なので、自分でタイムスタンプをチェックすることさえできます:
<*>
xargs -P
はジョブを並行して実行することもできますが、拡張機能の操作やそれを使用して複数のコマンドを実行するのは少し不便です: xargsを介した複数のコマンドの呼び出し
並列リンクは次の場所で尋ねられました: gccはリンク時に複数のコアを使用できますか?
TODO:コンパイルを行列の乗算に減らすことができることをどこかで読んだと思うので、大きなファイルの単一ファイルのコンパイルを高速化することもできます。しかし、私は今参照を見つけることができません。
Ubuntu 18.10。でテスト済み
| parallel -t --will-cite "\
if ! [ -f '{.}.o' ] || [ '{}' -nt '{.}.o' ]; then
gcc -c -o '{.}.o' '{}'
fi
"
xargs -P
はジョブを並行して実行することもできますが、拡張機能の操作やそれを使用して複数のコマンドを実行するのは少し不便です: xargsを介した複数のコマンドの呼び出し
並列リンクは次の場所で尋ねられました: gccはリンク時に複数のコアを使用できますか?
TODO:コンパイルを行列の乗算に減らすことができることをどこかで読んだと思うので、大きなファイルの単一ファイルのコンパイルを高速化することもできます。しかし、私は今参照を見つけることができません。
Ubuntu 18.10。でテスト済み
| parallel -t --will-cite "gcc -c -o '{.}.o' '{}'"説明:
-
{。}
は入力引数を取り、その拡張子を削除します -
-t
は実行中のコマンドを出力し、進行状況を把握します -
-will-cite
は、ソフトウェアを使用して結果を公開する場合にソフトウェアを引用する要求を削除します...
parallel
はとても便利なので、自分でタイムスタンプをチェックすることさえできます:
xargs -P
はジョブを並行して実行することもできますが、拡張機能の操作やそれを使用して複数のコマンドを実行するのは少し不便です: xargsを介した複数のコマンドの呼び出し
並列リンクは次の場所で尋ねられました: gccはリンク時に複数のコアを使用できますか?
TODO:コンパイルを行列の乗算に減らすことができることをどこかで読んだと思うので、大きなファイルの単一ファイルのコンパイルを高速化することもできます。しかし、私は今参照を見つけることができません。
Ubuntu 18.10。でテスト済み