複数のコアでコンパイルするときにmakeがハングする原因は何ですか?


17

昨日、ソースからROOTパッケージをコンパイルしようとしていました。6コアのモンスターマシンでコンパイルしていたので、先に進み、を使用して複数のコアを使用してビルドすることにしましたmake -j 6。コンパイルは最初はスムーズで非常に高速でしたが、ある時点でmake1つのコアで100%CPUを使用してハングしました。

私はいくつかのグーグル検索を行い、ROOT掲示板でこの投稿を見つけました。このコンピューターを自分で作ったので、ヒートシンクを適切に適用しておらず、CPUが過熱しているかどうかが心配でした。残念ながら、ここには冷蔵庫がありません。

lm-sensorsパッケージをインストールし、make -j 6再度実行しましたが、今回はCPU温度を監視しました。温度は高くなりましたが(60 Cに近い)、高温または臨界温度を超えることはありませんでした。

実行しようとしましたmake -j 4make、コンパイル中に別の場所で再びハングしました。

最終的には、実行中にコンパイルmakeしましたが、うまくいきました。私の質問は:なぜそれがぶら下がっていたのですか?2つの異なるスポットで停止したという事実により、何らかの競合状態が原因であると推測されmakeますが、-jオプションを提供しているため、すべてを適切な順序で取得するのに十分賢いはずです。


4
競合状態のように聞こえます。できることの1つは、実行中のmakeプロセス(スピンしているプロセス)にアタッチすることです。たとえばstrace -p <pid>、何を探しているのかを見つけられるかどうかを確認します。straceはsyscallのみを表示します(関数呼び出しは表示しません)が、特定のファイルを見ている間または特定のファイルを表示しているときに回転している場合、貴重な情報を提供できます。
jlp

Googleで見つけたスレッドは、誰もそれをコンパイルできないという結論に至り-j >1ます。
ニルス

並列コンパイルとは関係ありませんが、デバッグに永遠にかかったメイクファイルがハングしていました。$(shell ...)結局、それは単に変数の初期化にあり、最終的にはからの入力を待ってstdinいたコマンドを実行していたことがわかりました。これは、変数が空で、ファイル引数がコマンドに渡されなかった場合に発生していました。
jozxyqk

回答:


13

この正確な問題に対する答えはありませんが、何が起こっているかのヒントを提供しようとすることができます。Makefileに依存関係がありません。

例:

target: a.bytecode b.bytecode
    link a.bytecode b.bytecode -o target

a.bytecode: a.source
    compile a.source -o a.bytecode

b.bytecode: b.source
    compile b.source a.bytecode -o a.bytecode

make targetすべてを呼び出すと、正しくコンパイルされます。のコンパイルがa.source(任意に、しかし決定論的に)最初に実行されます。その後、のコンパイルb.sourceが実行されます。

ただし、make -j2 target両方のcompileコマンドが並行して実行される場合。そして、実際にMakefileの依存関係が壊れていることに気付くでしょう。2番目のコンパイルではa.bytecode、すでにコンパイルされていると想定されますが、依存関係には表示されません。そのため、エラーが発生する可能性があります。の正しい依存関係行はb.bytecode次のとおりです。

b.bytecode: b.source a.bytecode

問題に戻ると、運がよければ、依存関係が欠落しているために、コマンドが100%CPUループでハングする可能性があります。これはおそらくここで起こっていることです。欠落している依存関係はシーケンシャルビルドでは明らかにできませんでしたが、パラレルビルドでは明らかになっています。


面白い。メイクファイルを介して実行し、これらの依存関係を確認できるツールがあるかどうか知っていますか?
-user545424

知りません。いずれにせよ、そのようなツールは明らかな間違いを見つけることができるだけでした。Makefileに表示される各コマンドの構文を理解し、(潜在的に暗黙的な)依存関係を把握していない限り。
ステファンギメネス

2

マシンの使用期間はわかりませんが、最初の推奨事項は、メモリテストを試して、メモリが適切に機能していることを確認することです。多くの場合、問題の原因はメモリではないことを知っていますが、問題がある場合は、他のおそらく問題を突き止める前に、まず原因としてそれを排除するのが最善です。


1

これは非常に古い質問ですが、検索結果の上部に表示されるので、解決策を次に示します。

GNUのmakeはメイクを確保するためのジョブサーバメカニズムを有し、その再帰的な子供たちは、コアの指定した数よりも多くを消費しません。 http://make.mad-scientist.net/papers/jobserver-implementation/

すべてのプロセスで共有されるパイプに依存しています。追加の子をフォークしたい各プロセスは、最初にパイプからトークンを消費し、完了したらトークンを放棄する必要があります。子プロセスが消費したトークンを返さない場合、トップレベルのmakeは、返されるのを待って永久にハングします。

https://bugzilla.redhat.com/show_bug.cgi?id=654822

SolarisボックスでGNU makeを使用してbinutilsをビルドすると、このエラーが発生しました。「sed」はGNU sedではありません。PATHをいじってsed == gsedがシステムsedよりも優先されるようにして、問題を修正しました。sedがパイプからトークンを消費した理由はわかりませんが。


0

システムは大丈夫かもしれませんが、makeビルドを並行して実行しているときに競合状態が発生する可能性があります。

システムに何か問題がある場合、並列ビルドを行っているときだけでなく、他のシナリオでハング/クラッシュします。


0

これは競合状態である可能性がありますが、必要なすべてのコンパイルが並行して行われ、他のコンパイルを待機している場合、リンクはマシン上で時間がかかります。リンクが以前の必要なコンパイルを並行して待機している場合、コンパイルするスレッドが何であれ、リンクのCPU頻度が高くなると思います。

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