自动设置多核机器的作业(-j)标志?

时间:2011-01-24 03:38:21

标签: makefile parallel-processing build-script

我的机器上有一个包含大量核心的Makefile,但在编译项目时我似乎总是忘记编写-jX并且它需要的时间比它应该的长。

有什么方法可以通过环境变量或其他一些持久配置文件设置-j标志,这样make会在这台机器上自动并行执行多个作业吗?

10 个答案:

答案 0 :(得分:36)

我假设您正在使用Linux。这来自我的~/.bashrc

# parallel make
export NUMCPUS=`grep -c '^processor' /proc/cpuinfo`
alias pmake='time nice make -j$NUMCPUS --load-average=$NUMCPUS'

样本用法

samm@host src> echo $NUMCPUS
8
samm@host src> pmake

变为time nice make -j8 --load-average=8

要回答关于将此问题放入Makefile的具体问题,我觉得在我的Makefile上撒上这个逻辑并不实际。把它放到顶级Makefile也不是一个很好的解决方案,因为我经常从子目录构建并希望并行构建它们。但是,如果您有一个相当平坦的源层次结构,它可能适合您。

答案 1 :(得分:33)

MAKEFLAGS环境变量似乎可以传递属于每个make运行的标志(至少对于GNU make)。我自己也没有太多运气,但可以使用-l而不是-j来自动运行适合您可用核心数量的多个作业。

答案 2 :(得分:26)

正如Jeremiah Willcock所说,使用MAKEFLAGS,但这是如何做到的:

export MAKEFLAGS="-j $(grep -c ^processor /proc/cpuinfo)"

或者您可以像这样设置固定值:

export MAKEFLAGS="-j 8"

如果您真的希望提升效果,请在ccache添加以下内容时使用Makefile

CCACHE_EXISTS := $(shell ccache -V)
ifdef CCACHE_EXISTS
    CC := ccache $(CC)
    CXX := ccache $(CXX)
endif

答案 3 :(得分:15)

我通常在我的bash脚本中执行以下操作:

make -j$(nproc)

答案 4 :(得分:6)

您可以在Makefile中添加一行,类似于以下内容:

NUMJOBS=${NUMJOBS:-" -j4 "}

然后在规则中添加${NUMJOBS}行,或将其添加到另一个Makefile var(如MAKEFLAGS)中。这将使用NUMJOBS envvar(如果存在);如果没有,则自动使用-j4。您可以根据自己的喜好调整或重命名。

(注意:个人而言,我更喜欢默认为-j1"",特别是如果要将其分发给其他人,因为虽然我也有多个核心,但我会编译很多不同的平台,往往忘记 dis - -jX设置。)

答案 5 :(得分:6)

Aliases are not expanded inside scripts。最好创建一个单独的menuconfig脚本并将其放入make目录之一:

$PATH

答案 6 :(得分:2)

在2016年的某个时候,你可以把它放在你的makefile中:( GNU make tests)

MAKEFLAGS += "-j$(NUM_CORES) -l$(NUM_CORES)

(其中NUM_PPROCS是根据这里的许多其他答案之一计算或设定的)而且,bam!你正在进行多进程建设。

鉴于这已经停止工作,我能想到的最好的事情是,makefile调用自身,但使用-jX-lX

ifeq ($(PARALELL_WRAPPER_ABXCOEOEKCOEBMQJKHTOEUB),done)

all: ...
   ...

other_target: ...
    ...

else
# add parallelism equal to number of cores every time.
# "random" strings are to ensure uniqueness
NUM_CORES ?= $(shell grep -c "vendor_id" /proc/cpuinfo)
MAKEFLAGS +=" -j$(NUM_CORES) -l$(NUM_CORES) "

# for the default target case
parallel_wrapper_default_target_anthsqjkshbeohcbmeuthnoethoaeou:
    $(MAKE) PARALELL_WRAPPER_ABXCOEOEKCOEBMQJKHTOEUB=done

# catches everything else
% :
    $(MAKE) $@ PARALELL_WRAPPER_ABXCOEOEKCOEBMQJKHTOEUB=done

endif

答案 7 :(得分:2)

在使用所有CPU内核的Ubuntu 16.4上:

export MAKEFLAGS='-j$(nproc)'

export MAKEFLAGS='-j 2'

答案 8 :(得分:1)

在Makefile的开头:

MAKEFLAGS+="j"

任何版本的GNU Make before 4.2都不会使用数字参数。 4.2 you can do之后:

MAKEFLAGS+="j2"

对于早于4.2的版本,如果碰巧某些作业内存不足,则可以使用util-linux-ng中的flock一次只运行一个作业。例如,ImageMagick中的convert实用程序将使用它在用于optimize images according to Google's recommendations时可以获得的所有资源,因此没有必要让它并行运行。

%.min.jpg: %.jpg
    @flock --wait 600 Makefile convert $< -sampling-factor 4:2:0 -strip $@

设置较长的等待时间非常重要,因为make仍将并行运行大多数这些命令。因此,等待时间必须是最深的队列执行时间。如果您有八个核心,并且需要一分钟来优化八个大图像,则必须将等待时间设置为至少一分钟。

有数百个核心和巨大的图像,上面设置的六百秒可能还不够。

答案 9 :(得分:-1)

我会把

alias make='make -j'

~/.profile~/.bashrc

根据manual

  

如果在'-j'选项后看起来没有任何整数,则作业槽的数量没有限制。