69

我在一台有大量内核的机器上有一个 Makefile,但我似乎总是-jX在编译我的项目时忘记写,而且它花费的时间比它应该的要长。

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

4

10 回答 10

44

我假设您使用的是 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.

要回答您关于将其放入 a 的具体问题Makefile,我认为将这个逻辑散布在我的 Makefile 中是不切实际的。将其放入顶级 Makefile 也不是一个很好的解决方案,因为我经常从子目录构建并希望并行构建它们。但是,如果您有一个相当平坦的源层次结构,它可能对您有用。

于 2011-01-24T03:54:45.350 回答
38

似乎MAKEFLAGS环境变量可以传递作为每次make运行一部分的标志(至少对于 GNU make)。我自己对此并没有太多运气,但是可能可以使用-l而不是-j自动运行与您可用的内核数量相适应的尽可能多的作业。

于 2011-01-24T03:44:31.187 回答
33

正如 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
于 2013-12-06T04:32:48.337 回答
29

我通常在我的 bash 脚本中这样做:

make -j$(nproc)
于 2016-12-20T16:41:25.730 回答
6

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

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

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

(注意:就我个人而言,我更喜欢默认设置为-j1or "",尤其是当它要分发给其他人时,因为虽然我也有多个内核,但我在许多不同的平台上编译,并且经常忘记禁用-jX设置。 )

于 2011-01-24T03:44:40.370 回答
6

别名不会在脚本内展开。最好创建一个单独的make脚本并将其放入以下$PATH目录之一:

#!/bin/sh

if [ -f /proc/cpuinfo ]; then
    CPUS=`grep processor /proc/cpuinfo | wc -l`
else
    CPUS=1
fi
/usr/bin/make -j`expr $CPUS + 1` "$@"
于 2015-06-03T20:33:52.277 回答
2

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

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

NUM_PPROCS根据此处的许多其他答案之一计算或设置哪里)而且,砰!您正在进行多进程构建。

鉴于这已经停止工作,我能想到的最好的事情就是这个,makefile 调用自己的地方,但是使用-jXand -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
于 2017-06-10T21:53:11.537 回答
2

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

export MAKEFLAGS='-j$(nproc)'

或者

export MAKEFLAGS='-j 2'
于 2017-09-08T13:39:43.950 回答
1

在 Makefile 的开头:

MAKEFLAGS+="j"

It won't take numeric arguments for any version of GNU Make before 4.2. After 4.2 you can do:

MAKEFLAGS+="j2"

For versions earlier than 4.2 if you happen to have some jobs running out of memory, you could make them run only one at a time with flock from util-linux-ng. For example, a convert utility from ImageMagick will use all resources it can get when used to optimize images according to Google's recommendations, so there's no point to have it run in parallel.

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

It is important to set a long wait time because make will still run most of these commands in parallel. Therefore, wait time must be as such as the deepest queue execution time. If you have eight cores, and eight large images take a minute to optimize, you must set the wait time to at least a minute.

With hundreds of cores and huge images, six hundred seconds set above might not be enough.

于 2017-12-27T03:33:41.950 回答
-2

我只想把

alias make='make -j'

~/.profile~/.bashrc

根据手册

如果在“-j”选项之后没有看起来像整数的东西,则作业槽的数量没有限制。

于 2013-06-05T14:57:40.630 回答