2017-03-17 44 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的情況。 –