멀티 코어 시스템에 대한 작업 (-j) 플래그를 자동으로 설정 하시겠습니까?
많은 코어가있는 머신에 Makefile이 있지만 항상 -jX
프로젝트를 컴파일 할 때 작성하는 것을 잊은 것 같고 예상보다 오래 걸립니다.
-j
make가이 컴퓨터에서 여러 작업을 병렬로 자동으로 실행하도록 환경 변수 또는 다른 영구 구성 파일을 통해 플래그를 설정할 수있는 방법 이 있습니까?
MAKEFLAGS
환경 변수가 모든 make
실행의 일부인 플래그를 전달할 수 있는 것으로 보입니다 (적어도 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
위해이 논리를 내 Makefile 전체에 뿌리는 것이 실용적이지 않습니다. 이것을 최상위 Makefile에 넣는 것은 종종 하위 디렉토리에서 빌드하고 병렬로 빌드하기를 원하기 때문에 훌륭한 솔루션이 아닙니다. 그러나 소스 계층 구조가 상당히 평평한 경우에는 적합 할 수 있습니다.
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)
Makefile에 다음과 유사한 행을 추가 할 수 있습니다.
NUMJOBS=${NUMJOBS:-" -j4 "}
그런 다음 ${NUMJOBS}
규칙에 줄을 추가하거나 다른 Makefile
변수 (예 :)에 추가합니다 MAKEFLAGS
. 존재하는 경우 NUMJOBS envvar를 사용합니다. 그렇지 않은 경우 자동으로 -j4
. 취향에 맞게 조정하거나 이름을 바꿀 수 있습니다.
(주의 : 개인적으로, 나는 될 수있는 기본을 선호하는 것 -j1
또는 ""
, 다른 사람에게 배포 할 것 특히, 나 또한 여러 개의 코어를 가지고 있지만, 나는 많은 다른 플랫폼에서 컴파일하기 때문에, 종종 잊지 창피 -able -jX
설정. )
별칭은 스크립트 내에서 확장되지 않습니다 . 별도의 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` "$@"
모든 CPU 코어를 사용하는 Ubuntu 16.4에서 :
export MAKEFLAGS='-j$(nproc)'
또는
export MAKEFLAGS='-j 2'
2016 년까지 메이크 파일에 다음을 넣을 수 있습니다 : (GNU make testing)
MAKEFLAGS += "-j$(NUM_CORES) -l$(NUM_CORES)
( NUM_PPROCS
여기에 다른 많은 답변 중 하나에 따라 계산되거나 설정되는 위치) 그리고, bam! 다중 프로세스 구축이 진행 중입니다.
이것이 작동을 멈췄다는 점을 감안할 때 내가 생각해 낼 수있는 가장 좋은 것은 makefile이 스스로를 호출하지만 -jX
and -lX
.
ifeq ($(PARALELL_WRAPPER_ABXCOEOEKCOEBMQJKHTOEUB),done)
all: ...
...
other_target: ...
...
else
# add parallelism equal to number of cores every time.
# "random" strings are to ensure uniqueness
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
endif
Makefile 시작 부분 :
MAKEFLAGS+="j"
4.2 이전 의 GNU Make 버전에 대해서는 숫자 인수를 사용하지 않습니다 . 4.2 이후에는 다음을 수행 할 수 있습니다 .
MAKEFLAGS+="j2"
For versions earlier than 4.2 if you happen to have some jobs running out of memory, you could make them run only one at a time with flock
from util-linux-ng. For example, a convert
utility from ImageMagick will use all resources it can get when used to optimize images according to Google's recommendations, so there's no point to have it run in parallel.
%.min.jpg: %.jpg
@flock --wait 600 Makefile convert $< -sampling-factor 4:2:0 -strip $@
It is important to set a long wait time because make will still run most of these commands in parallel. Therefore, wait time must be as such as the deepest queue execution time. If you have eight cores, and eight large images take a minute to optimize, you must set the wait time to at least a minute.
With hundreds of cores and huge images, six hundred seconds set above might not be enough.
I would just put
alias make='make -j'
in ~/.profile
or ~/.bashrc
.
According to the manual:
If there is nothing looking like an integer after the ‘-j’ option, there is no limit on the number of job slots.
'Programing' 카테고리의 다른 글
표 셀에서 링크를 만들 수있는 방법 (0) | 2020.12.11 |
---|---|
.NET에서 스레드를 깨끗하게 종료하는 것에 대한 질문 (0) | 2020.12.11 |
hazelcast 대 ehcache (0) | 2020.12.11 |
2 바이트 배열을 결합하는 방법 (0) | 2020.12.11 |
mvnrepository.com의 maven 프로필을 알고 있습니까? (0) | 2020.12.11 |