2017-03-17 78 views
2

运行make与-j使用所有可用的核心标志,但是这有时会导致线程鞭打或其他不好的事情发生。n-1核心的一个衬垫?

在bash脚本,我该如何使用n-1内核,而不是(仅当n>1另有1)。

必须有做比这更简单的方法:

NJOBS=$((`getconf _NPROCESSORS_ONLN 2>/dev/null \ 
    || sysctl hw.ncpu \ 
    || echo 2` \ 
    - 1)) 
+0

顺便说一句,'NJOBS'全部大写并不是好的形式 - 参见[POSIX Issue 7关于环境变量的规范](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html),它指定全部大写名称用于对操作系统和shell有意义的变量,并且至少包含一个小写字符的名称保留给应用程序使用。由于设置shell变量将覆盖任何类似命名的环境变量,因此该公约也适用于此。 –

+0

即使你不那么简单的解决方案不处理'n = 1'的情况,或者我错过了什么?例如, – 5gon12eder

回答

3

整个原因,你当前的代码并不简单的是,它试图完成具有跨多个没有标准接口的操作操作系统。因此,为具有当前操作系统上工作的方法的最佳机会,它通过多种可能性:

  • getconf _NPROCESSORS_ONLN在Linux和MacOS X,而不能承载Solaris,FreeBSD的,NetBSD的,等等。
  • sysctl hw.ncpu作品上大多数非Solaris系统。
  • 2是安全默认值,如减去1将返回只有一个核心的价值。

在Solaris上运行,一个希望添加psrinfo -p可能的回退列表中,从而使你的代码甚至更详细


如果你愿意妥协便携一点(但仍保持了最后一搏回退,所以我们如果在Solaris上运行的不完全失败),

ncores=$(sysctl hw.ncpu); njobs=$((ncores > 1 ? (ncores - 1) : 1)) 

也许是合理的妥协(并处理案例,原来没有,成功返回值1)。

1

在化妆的-j参数可以采用一个参数作为芯使用的数量。因此,你可以这样做:

CORES := $(shell grep -c ^processor /proc/cpuinfo) 
JFLAG := $(shell echo "-j$$(($(CORES) - 1 ? $(CORES) - 1 : 1))" 

all: 
    $(MAKE) $(JFLAG) _some_sub_makefile..._ 

如果你希望你的化妆覆盖传递给它的-j标志,你这样做:

ifeq (,$(filter DASHJSET,$(MAKECMDGOALS))) 

ABSPATH := $(abspath $(lastword $(MAKEFILE_LIST))) 

CORES := $(shell grep -c ^processor /proc/cpuinfo) 
JFLAG := $(shell echo "-j$$(($(CORES) - 1 ? $(CORES) - 1 : 1)))" 

all: 
    $(MAKE) -C $(ABSPATH) $(JFLAG) DASHJSET $(MAKECMDGOALS) 

.PHONY: DASHJSET 

fi 
+0

'grep -c^processor/proc/cpuinfo'完全是Linux-only - 完全无法在Mac上运行。 OP还没有在问题中标记或以其他方式指出他们的操作系统。 –

+0

不错,需要优雅地处理单CPU的情况。 –

相关问题