制作-j RAM限制

时间:2012-07-24 21:24:08

标签: makefile

有没有办法强迫make -j不要过度使用我的内存?我在一个开发团队工作,我们有不同的硬件集,所以-j8可能不适合每个人。但是,make -j为我使用了太多内存,并溢出到交换中,这可能会占用整个系统。我怎么能避免这个?

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

4 个答案:

答案 0 :(得分:5)

还有另一种方法可以做到这一点:

(来自http://www.gnu.org/software/make/manual/html_node/Parallel.html#Parallel

  

当系统负载很重时,您可能希望运行更少   工作比轻载时。您可以使用'-l'选项   告诉make限制一次运行的作业数量,基于   平均负载。 '-l'或'--max-load'选项后跟a   浮点数。例如,

     如果负载平均值高于2.5,

-l 2.5将不会让make启动多个作业。没有以下编号的'-l'选项将删除   加载限制,如果使用之前的'-l'选项给出。

如果您担心所有RAM都会被占用,这可能有所帮助。在这种情况下,“加载”是指正常运行时间或最高报告。如果你正在交换,或者更糟糕的是,捶打,负载将会上升。您可以试验此选项的值。您应该在非并行构建期间观察负载级别,并在增加make的并行进程数时观察。这应该为您的机器提供合理的基线。

答案 1 :(得分:4)

稍微简单的解决方案是每个工作站都有一个适合硬件可以处理的环境变量。让makefile读取此环境变量并将其传递给-j选项。 How to get gnu make to read env variables.

此外,如果构建过程有很多步骤并且花费很长时间make重新读取环境变量,那么在构建期间您可以减少/增加资源使用。

此外,可能在工作站上运行服务/应用程序来监视资源使用情况并修改环境变量,而不是尝试make执行此操作...

答案 2 :(得分:0)

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

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

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

make -j `nproc`

答案 3 :(得分:0)

可以使用ulimit来限制进程RAM的使用。但是,如果超出限制,可能会导致处理失败。 gcc喜欢在单线程中进行链接时超过任何限制。因此ulimit解决方案并不受欢迎。

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

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

#!/bin/bash

# We need up to 1000 MB (less than 1GB) per thread.
MAX_THREADS=$(($(getconf _PHYS_PAGES) * $(getconf PAGE_SIZE) / (1000 ** 3)))
EFFECTIVE_THREADS=$(getconf _NPROCESSORS_ONLN)
THREADS=$((MAX_THREADS < EFFECTIVE_THREADS ? MAX_THREADS : EFFECTIVE_THREADS))

MAX_JOBS=$((MAX_THREADS / THREADS))
JOBS=$((MAX_JOBS < EFFECTIVE_THREADS ? MAX_JOBS : EFFECTIVE_THREADS))

MAX_LOAD=$((EFFECTIVE_THREADS * 9 / 10))

export MAKEOPTS="--jobs=$THREADS --load-average=$MAX_LOAD"
export EMERGE_DEFAULT_OPTS="--jobs=$JOBS --load-average=$MAX_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"创建的。如果要添加/删除轻/重选项,请重新估算。