自动为多核机器设置作业(-j)标志?
我在一个拥有大量内核的机器上有一个Makefile,但是编译我的项目时似乎总是忘记写-jX
,并且它比预期的要长。
有什么办法可以通过环境variables或其他持久化configuration文件来设置-j
标志,这样make就可以在这台机器上自动执行多个作业?
看来MAKEFLAGS
环境variables可以传递每个make
运行的标志(至less对于GNU make来说)。 我自己也没有太多的运气,但可以使用-l
而不是-j
来自动运行尽可能多的作业,而这些作业适合于可用核心的数量。
我假设你正在使用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
,我觉得把这个逻辑遍布在我的Makefiles上是不现实的。 把它放到顶层Makefile中也不是一个好的解决scheme,因为我经常从子目录构build,并且希望并行构build它们。 但是,如果你有一个相当平坦的源代码层次结构,它可能适合你。
正如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
我通常在我的bash脚本中如下所示:
make -j$(nproc)
您可以添加一行到您的生成文件类似于以下内容:
NUMJOBS=${NUMJOBS:-" -j4 "}
然后在规则中添加${NUMJOBS}
行,或将其添加到另一个Makefile
var(如MAKEFLAGS
)中。 这将使用NUMJOBS envvar(如果存在); 如果没有,则自动使用-j4
。 您可以调整或重命名为您的口味。
(注:就个人而言,我宁愿默认设置为-j1
或""
,特别是如果要分配给其他人,因为虽然我也有多个内核,但是我在许多不同的平台上编译,能够使用-jX
设置。)
脚本中不会扩展别名 。 最好创build一个单独的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` "$@"
直到去年的某个时候,你可以在你的makefile中做这个:(GNU make testing)
MAKEFLAGS += "-j$(NUM_CORES) -l$(NUM_CORES)
(其中NUM_PPROCS
根据这里的许多其他答案之一计算或设置)并且,砰! 你有多进程的build设。
鉴于这已经停止工作,我可以想到的最好的事情是这样的,makefile调用自己,但与-jX
和-lX
。
# add parallelism equal to number of cores every time. # it seems that adding -jX to MAKEFLAGS directly doesn't work any more. # included some "random" strings to ensure uniqueness ifneq ($(PARALELL_WRAPPER_ABXCOEOEKCOEBMQJKHTOEUB),done) 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 # the match for this else is at the end of the file else ##### rest of makefile here ##### all: ... ... other_target: ... ... ##### etc. ##### endif
在使用所有CPU核心的Ubuntu 16.4上:
export MAKEFLAGS='-j$(nproc)'
要么
export MAKEFLAGS='-j 2'
我只会放
alias make='make -j'
在~/.profile
或~/.bashrc
。
根据手册 :
如果在'-j'选项之后没有看起来像整数,那么作业槽的数量没有限制。