Makefile Make-j RAM限制

Makefile Make-j RAM限制,makefile,Makefile,有没有办法强迫make-j不要过度消耗我的RAM?我在一个开发团队工作,我们有不同的硬件设置,所以-j8可能不是每个人的最佳选择。然而,make-j对我来说使用了太多的RAM,并溢出到交换中,这可能会破坏我的整个系统。我怎样才能避免这种情况 理想情况下,我希望能够监视系统负载并停止生成新线程,等待一些线程完成,然后继续 有些简单的解决方案是,每个工作站都有一个适合硬件处理的环境变量。让makefile读取此环境变量并将其传递给-j选项 另外,如果构建过程有许多步骤并且需要很长时间,请让make重

有没有办法强迫
make-j
不要过度消耗我的RAM?我在一个开发团队工作,我们有不同的硬件设置,所以
-j8
可能不是每个人的最佳选择。然而,
make-j
对我来说使用了太多的RAM,并溢出到交换中,这可能会破坏我的整个系统。我怎样才能避免这种情况


理想情况下,我希望能够监视系统负载并停止生成新线程,等待一些线程完成,然后继续

有些简单的解决方案是,每个工作站都有一个适合硬件处理的环境变量。让makefile读取此环境变量并将其传递给-j选项

另外,如果构建过程有许多步骤并且需要很长时间,请让
make
重新读取环境变量,以便在构建过程中减少/增加资源使用


此外,可能在工作站上运行一个服务/应用程序,用于监视资源使用情况并修改环境变量,而不是试图让
使
这样做…

还有另一种方法:

(来自)

当系统负载较重时,您可能希望运行更少的系统 作业比轻加载时的作业多。您可以使用“-l”选项 告诉make限制一次运行的作业数,具体取决于 平均负荷。“-l”或“--max load”选项后面跟一个 浮点数。比如说,

-如果平均负载高于2.5,则L2.5不允许make启动多个作业。不带以下编号的“-l”选项将删除 负载极限,如果使用先前的'-l'选项给出


如果你担心你所有的公羊都会被霸占,这会有所帮助在这种情况下,“加载”是指正常运行时间或top报告。如果你在交换,或者更糟的是,在颠簸,负载会迅速上升。您可以尝试使用此选项的值。您应该在非并行构建期间观察负载级别,并观察make的并行进程数量的增加。这应该为您的机器提供一个合理的基线。

是否可能对make-j的功能有一些混淆?(至少我错了很长一段时间…)。我假设不带选项的-j将适应CPU的数量,但它没有-它根本没有应用任何限制。这意味着对于大型项目,它将创建大量的进程(只需运行“top”即可查看…),并且可能会耗尽所有RAM。当我的项目的“make-j”使用了我所有的16Gb内存并失败时,我偶然发现了这一点,而“make-j 8”在2.5GB内存使用率下达到了顶峰(在8个内核上,两种情况下的负载都接近100%)

就效率而言,我认为使用一个等于或大于您期望的最大CPU数量的限制比没有限制更有效,因为数千个进程的调度有一些开销。创建的进程总数应该是常量,但由于“-j”一次创建了很多进程,内存分配可能会成为一个问题。即使将限制设置为CPU数量的两倍,也应该比完全不设置限制更加保守

PS:在进一步挖掘之后,我想出了一个简洁的解决方案——只需读出处理器的数量,并将其用作-j选项:

make -j `nproc`

可以使用
ulimit
限制进程RAM的使用。但当超过限制时,可能会导致流程失败<代码>gcc
喜欢在单线程中链接时超出任何限制。因此,
ulimit
解决方案并不流行

另一个解决方案是提供每个线程的
gcc
RAM使用量估计,并维护很少使用的交换。您可以添加
load average
,以在负载过高时停止生成新线程/作业

我正在使用以下脚本
/etc/profile.d/makeopts.sh
(gentoo):

#/bin/bash
#每个线程最多需要1000 MB(小于1GB)。
最大线程数=$($(getconf物理页面)*$(getconf页面大小)/(1000**3)))
有效线程=$(getconf\u处理器)
线程=$((最大线程<有效线程?最大线程:有效线程))
最大作业数=$((最大线程数/线程数))
作业=$((最大作业<有效线程?最大作业:有效线程))
最大负载=$((有效线程*9/10))
export MAKEOPTS=“--作业=$THREADS--平均负载=$MAX\u负载”
export EMERGE\u DEFAULT\u OPTS=“--jobs=$jobs--load average=$MAX\u load”
具有4个线程和16 GB RAM的机器:

MAKEOPTS=“--jobs=4--load average=3”
EMERGE_DEFAULT_OPTS=“--jobs=4--load average=3”
具有16个线程和32 GB RAM的机器:

MAKEOPTS=“--jobs=16--load average=14”
EMERGE_DEFAULT_OPTS=“--jobs=2--load average=14”

请注意,此配置是为
CFLAGS=“-O2-pipe-march=native”
创建的。如果您想添加/删除轻/重选项,请重新估计它。

make--version
报告GNU make 3.81未经验证,我认为这可以通过在people's
.bashrc
中设置
-j
参数来解决,而不是在构建脚本中设置。唯一的问题是我们有不同的硬件设置。但这可能行得通。不要紧,一个合理的负载限制应该完全满足您的需求,基本上独立于硬件。我也可以用斜体输入。@keith.layne是的,很好。在这种情况下,假设负载与RAM使用相关,这是错误的。Load是未阻止的线程数。如果您正在分页,则会被阻止,并且不会显示在加载编号中。在内存不足的情况下,您将进行分页。您将在内存不足的情况下使用此建议启动“更多”作业,这不是您想要的。硬件可以处理的内容取决于正在编译的内容,并且不能由make-j进行最佳控制,因为-j选项不知道构建各种类型的源时所需的RAM使用情况。例如,-O0对-O2或C对C