dla*_*tte 28 parallel-processing makefile
不确定单独在一个Makefile中是否可以这样做,但是我希望以这样的方式编写Makefile,以便尝试在文件中构建任何目标,自动神奇地检测当前系统上的处理器数量并并行构建目标对于处理器的数量.
像下面的"伪代码"示例,但更干净?
all:
@make -j$(NUM_PROCESSORS) all
Run Code Online (Sandbox Code Playgroud)
要么:
all: .inparallel
... build all here ...
.inparallel:
@make -j$(NUM_PROCESSORS) $(ORIGINAL_TARGET)
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,您只需输入以下内容:
% make all
Run Code Online (Sandbox Code Playgroud)
希望这是有道理的.
更新:仍然希望上面的Makefile示例.对找到进程数并不感兴趣,但对如何在没有-j命令行选项的情况下编写并行构建的makefile感兴趣.
dmc*_*kee 23
检测部分将取决于操作系统.这是一个适用于Linux和Mac OS X的片段:
NPROCS:=1
OS:=$(shell uname -s)
ifeq($(OS),Linux)
NPROCS:=$(shell grep -c ^processor /proc/cpuinfo)
endif
ifeq($(OS),Darwin) # Assume Mac OS X
NPROCS:=$(shell system_profiler | awk '/Number Of CPUs/{print $4}{next;}')
endif
Run Code Online (Sandbox Code Playgroud)
为了使它工作,你可能不得不重新调用make.那你的问题是阻止无限递归.您可以通过使用两个makefile(第一个仅重置-j值)来管理它,但可能会对它进行精细化处理.
小智 7
我刚把它添加到我的Makefile的顶部.它允许创建任意数量的作业,但尝试将负载平均值保持在cpu核心数之下.
MAKEFLAGS+="-j -l $(shell grep -c ^processor /proc/cpuinfo) "
Run Code Online (Sandbox Code Playgroud)
请注意,这是特定于Linux的.
稍微探讨了LDD3第2章并阅读了dmckee的回答后,我想出了使用两个makefile的不太好的答案(我更喜欢只有一个).
$ cat Makefile
MAKEFLAGS += -rR --no-print-directory
NPROCS := 1
OS := $(shell uname)
export NPROCS
ifeq ($J,)
ifeq ($(OS),Linux)
NPROCS := $(shell grep -c ^processor /proc/cpuinfo)
else ifeq ($(OS),Darwin)
NPROCS := $(shell system_profiler | awk '/Number of CPUs/ {print $$4}{next;}')
endif # $(OS)
else
NPROCS := $J
endif # $J
all:
@echo "running $(NPROCS) jobs..."
@$(MAKE) -j$(NPROCS) -f Makefile.goals $@
%:
@echo "building in $(NPROCS) jobs..."
@$(MAKE) -j$(NPROCS) -f Makefile.goals $@
$ cat Makefile.goals
MAKEFLAGS += -rR --no-print-directory
NPROCS ?= 1
all: subgoal
@echo "$(MAKELEVEL) nprocs = $(NPROCS)"
subgoal:
@echo "$(MAKELEVEL) subgoal"
Run Code Online (Sandbox Code Playgroud)
您对此解决方案有何看法?
我看到的好处是人们仍然make打算建立.因此,不存在一些"驱动程序"脚本,并NPROCS与make -j$(NPROCS)人们必须知道,而不是打字使工作.
缺点是您必须明确使用make -f Makefile.goals才能进行串行构建.而且我不确定如何解决这个问题......
更新:在上面的代码段中添加了$ J. 似乎工作很顺利.即使它的两个makefile而不是一个,它仍然非常无缝和有用.
这就是我的用途:
ifeq ($(OS),Linux)
NUMPROC := $(shell grep -c ^processor /proc/cpuinfo)
else ifeq ($(OS),Darwin)
NUMPROC := $(shell sysctl hw.ncpu | awk '{print $$2}')
endif
# Only take half as many processors as available
NUMPROC := $(shell echo "$(NUMPROC)/2"|bc)
ifeq ($(NUMPROC),0)
NUMPROC = 1
endif
Run Code Online (Sandbox Code Playgroud)
我将跳过$(NPROCS)检测的东西,但是这里你可以在一个单独的地方做这个Makefile(这可能是GNU Make特定的,但看起来像你正在运行的变体):
ifeq ($(NPROCS),)
# Code to set NPROCS...
%:
$(MAKE) -j$(NPROCS) NPROCS=$(NPROCS)
else
# All of your targets...
endif
Run Code Online (Sandbox Code Playgroud)
请参阅GNU Make Manual中的定义Last-Resort默认规则和覆盖另一个Makefile的一部分.