在多核上编译时,可能导致make挂起的原因是什么?


17

昨天我正尝试从源代码编译ROOT软件包。由于我是在6核怪物机器上进行编译的,因此我决定继续使用并使用多核进行构建make -j 6。最初编译过程非常顺利,而且速度非常快,但有时make仅在一个内核上使用100%CPU即可挂起。

我进行了一些谷歌搜索,并在ROOT留言板上找到此帖。自从我自己构建了这台计算机以来,我担心自己没有正确安装散热器,并且CPU过热或其他原因。不幸的是,我在工作中没有冰箱可以插入。;-)

我安装了lm-sensors软件包并make -j 6再次运行,这次监视CPU温度。尽管温度很高(接近60摄氏度),但从未超过高温或临界温度。

我尝试运行,make -j 4但是make在编译过程中的某个时间再次挂起,这次是在另一个位置。

最后,我仅在运行时进行编译make,并且运行良好。我的问题是:为什么挂了?由于它停在两个不同的位置,我想这可能是由于某种比赛条件造成的,但是我认为make应该聪明到足以使所有东西都处于正确的顺序,因为它提供了-j选择。


4
听起来确实像是比赛条件。您可以做的一件事是使用附加到正在运行的make流程(正在旋转的流程)上,例如strace -p <pid>,查看是否可以找到其查找/查找的内容。strace仅显示系统调用(而不是函数调用),但是如果在查看或查找特定文件时旋转,它仍可以为您提供有价值的信息。
jlp 2012年

您通过google找到的线程得出的结论是,没有人可以使用进行编译-j >1
尼尔斯2012年

与并行编译无关,但是我有一个挂起的makefile,需要花大量的时间进行调试。事实证明,这只是在变量的初始化中,$(shell ...)最终运行的命令正在等待来自的输入stdin。这是由于变量为空并且没有文件参数传递给命令而引起的。
jozxyqk 2014年

Answers:


13

对于这个精确的问题,我没有答案,但是我可以尝试向您提示可能发生的情况: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循环中。这可能就是这里发生的情况,缺少的依存关系无法通过顺序构建来揭示,但已通过并行构建来揭示。


有趣。您是否知道是否有任何工具可以通过Makefile运行并检查这些依赖性?
user545424

我什么都不知道 无论如何,这样的工具只能发现明显的错误。除非它了解Makefile中出现的每个命令的语法,并且知道什么(潜在的隐式)依赖项。
斯特凡希门尼斯

2

我不知道您使用计算机的时间,但是我的第一个建议是尝试进行内存测试,并验证内存是否正常运行。我知道问题通常不是内存,但如果是,最好先排除原因,然后再尝试查找其他可能的问题。


1

我意识到这是一个非常老的问题,但是它仍然出现在搜索结果的顶部,所以这是我的解决方案:

GNU make拥有一个jobserver机制,以确保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频率都会很高。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.