Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/magento/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Makefile 自动设置多核机器的作业(-j)标志?_Makefile_Parallel Processing_Build Script - Fatal编程技术网

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

Makefile 自动设置多核机器的作业(-j)标志?,makefile,parallel-processing,build-script,Makefile,Parallel Processing,Build Script,我在一台有很多内核的机器上有一个Makefile,但在编译我的项目时,我似乎总是忘记编写-jX,而且所花的时间比它应该花的时间长 是否有某种方法可以通过环境变量或其他持久配置文件设置-j标志,以便make在此机器上自动并行执行多个作业?似乎MAKEFLAGS环境变量可以传递作为每个make运行的一部分的标志(至少对于GNU make而言)。我自己在这方面运气不太好,但是可以使用-l而不是-j来自动运行与可用内核数量相应的作业。您可以在make文件中添加一行,如下所示: NUMJOBS=${NUM

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


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

似乎
MAKEFLAGS
环境变量可以传递作为每个
make
运行的一部分的标志(至少对于GNU make而言)。我自己在这方面运气不太好,但是可以使用
-l
而不是
-j
来自动运行与可用内核数量相应的作业。

您可以在make文件中添加一行,如下所示:

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


(注意:就我个人而言,我更喜欢默认值为
-j1
“”
,尤其是当它要分发给其他人时,因为尽管我也有多个内核,但我在许多不同的平台上编译,并且经常忘记禁用
-jX
设置。)我假设您正在使用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也不是一个很好的解决方案,因为我经常从子目录进行构建,并希望并行构建它们。但是,如果您有一个相当平坦的sourc这可能对你有用。

我想

alias make='make -j'
~/.profile
~/.bashrc

根据报告:

如果在“-j”选项后没有任何看起来像整数的内容,则作业槽的数量没有限制


正如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
。最好创建一个单独的
make
脚本,并将其放入
$PATH
目录之一:

!/bin/sh
如果[-f/proc/cpuinfo];则
CPU=`grep processor/proc/cpuinfo | wc-l`
其他的
CPU=1
fi
/usr/bin/make-j`expr$cpu+1`“$@”

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

make -j$(nproc)

直到2016年的某个时候,您可以将其放在您的makefile中:(GNU make tested)

(其中,
NUM\u PPROCS
是根据此处许多其他答案中的一个进行计算或设置的)并且,bam!您正在进行多进程构建

考虑到这已经停止工作,我能想到的最好的办法是,makefile调用自己,但是使用
-jX
-lX


在Ubuntu 16.4上,使用所有CPU核:

export MAKEFLAGS='-j$(nproc)'


在生成文件的开头:

MAKEFLAGS+="j"
对于任何版本的GNU Make,它都不接受数字参数。4.2之后:

对于4.2之前的版本,如果您碰巧有一些作业内存不足,可以使用util linux ng中的
flock
使它们一次只运行一个。例如,ImageMagick中的
convert
实用程序将使用它使用时可以获得的所有资源,因此并行运行没有意义

%.min.jpg: %.jpg
    @flock --wait 600 Makefile convert $< -sampling-factor 4:2:0 -strip $@
%.min.jpg:%.jpg
@flock--等待600 Makefile convert$<-采样系数4:2:0-带$@
设置较长的等待时间很重要,因为make仍将并行运行这些命令中的大多数。因此,等待时间必须与最深的队列执行时间相同。如果您有八个内核,并且八个大映像需要一分钟来优化,则必须将等待时间设置为至少一分钟


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

谢谢你的回答。我同意耶利米的回答,因为它更容易理解,而且我根本不需要修改makefile(让下载项目的人随意设置-j标志).尽管如此。据我所知,在去年的某个时候,向MAKEFLAGS添加-jX已经停止了GNU make最新版本的工作。还有其他人经历过这种情况吗?自动检测内核数量的好主意。尽管我最终选择了$((numpus*2))由于这是我通常使用的编译工具。谢谢!%windows系统上的gnu make可以使用%u个处理器%。请注意:
nproc
在某些较旧的发行版上不存在(看着你,RHEL5)。手册页中关于
nproc
的附加说明:“打印当前进程可用的处理单元数量,可能少于联机处理器的数量”相关:@sanmai,您需要它用于哪个操作系统?为什么不
alias make='make-j$(getconf\u NPROCESSORS\u ONLN)“
为您工作?Alias不够用,因为我需要发布Makefile并让它继续工作。我需要这个用于GNU Make 4.1。@Tarunalwanion我的2核机器一个不合格的
-j
会在一个大的构建中很快耗尽我的所有内存。不推荐使用。是的,这似乎会在您的计算机上造成一个带有大型Makefile。您可以传递
-l
-j
,但不带参数。请自己尝试:注意传递
-l
会禁用负载限制功能,而没有参数的
-j
会告诉
make
启动无限数量的并行
export MAKEFLAGS='-j 2'
MAKEFLAGS+="j"
MAKEFLAGS+="j2"
%.min.jpg: %.jpg
    @flock --wait 600 Makefile convert $< -sampling-factor 4:2:0 -strip $@