在多核上編譯時可能導致 make 掛起的原因是什麼?
昨天我試圖從原始碼編譯ROOT包。由於我是在 6 核怪物機器上編譯它,我決定繼續使用
make -j 6
. 起初編譯非常順利而且非常快,但在某個時候make
,僅在一個核心上使用 100% CPU 就會掛起。我做了一些Google搜尋,在 ROOT 留言板上找到了這篇文章。由於我自己製造了這台電腦,我擔心我沒有正確安裝散熱器並且CPU過熱或其他什麼。不幸的是,我工作時沒有冰箱可以放進去。;-)
我安裝了
lm-sensors
軟體包並make -j 6
再次執行,這次是監控 CPU 溫度。雖然它變得很高(接近 60 攝氏度),但它從未超過高溫或臨界溫度。我嘗試執行
make -j 4
,但在編譯期間的某個時間再次make
掛起,這次是在不同的位置。最後,我編譯只是執行
make
,它工作正常。我的問題是:為什麼它掛了?由於它停在兩個不同的位置,我猜這是由於某種競爭條件,但我認為make
應該足夠聰明,讓一切都按正確的順序排列,因為它提供了-j
選項。
我對這個確切的問題沒有答案,但我可以嘗試給你一個可能發生的提示:Makefiles 中缺少依賴項。
例子:
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 的依賴關係被破壞了。第二個編譯假定a.bytecode
已經編譯,但它沒有出現在依賴項中。所以很可能會發生錯誤。正確的依賴行b.bytecode
應該是:b.bytecode: b.source a.bytecode
回到您的問題,如果您不走運,則可能由於缺少依賴項,命令會在 100% CPU 循環中掛起。這可能就是這裡發生的事情,順序建構無法揭示缺失的依賴關係,但您的並行建構已經揭示了它。