GNU make의 -j 옵션
-j에 대해 배운 이후로 나는 -j8을 가볍게 사용했습니다. 다른 날 나는 아틀라스 설치를 컴파일하고 있었고 make가 실패했습니다. 결국 나는 순서가 잘못된 것들까지 추적했고 단일 스레드 make로 돌아가면 제대로 작동했습니다. 이것은 나를 긴장하게 만든다. make -j를 사용하여 예기치 않은 작업을 수행하지 않도록 직접 make 파일을 작성할 때 어떤 종류의 조건을 관찰해야 합니까?
make -j는 Makefile에서 지정한 종속성을 존중할 것이라고 생각합니다. 즉, objA가 objB와 objC에 의존한다고 지정하면 make는 objB와 objC가 완료될 때까지 objA에서 작업을 시작하지 않습니다.
Makefile이 필요한 작업 순서를 충분히 엄격하게 지정하지 않았을 가능성이 높으며 단일 스레드의 경우에 작동하는 것은 운이 좋습니다.
간단히 말해서 종속성이 정확하고 완전한지 확인하십시오.
단일 스레드 make를 사용하는 경우 대상 간의 암시적 종속성을 맹목적으로 무시할 수 있습니다. 병렬 make를 사용할 때 암시적 종속성에 의존할 수 없습니다. 모두 명시해야 합니다. 이것은 아마도 가장 일반적인 함정일 것입니다. 특히 .phony 대상을 종속성으로 사용하는 경우.
이 링크는 병렬 연결과 관련된 몇 가지 문제에 대한 좋은 입문서입니다.
다음은 병렬 빌드를 사용하기 시작할 때 직면한 문제의 예입니다. 대상을 처음부터 다시 빌드하는 데 사용하는 "신선한" 대상이 있습니다("신선한" 빌드). 과거에는 단순히 "clean"을 표시한 다음 종속성으로 "build"를 표시하여 "fresh" 대상을 코딩했습니다.
build: ## builds the default target
clean: ## removes generated files
fresh: clean build ## works for -j1 but fails for -j2
병렬 빌드를 사용하기 시작할 때까지는 잘 작동했지만 병렬 빌드에서는 "정리"와 "빌드"를 동시에 시도합니다. 그래서 정확한 작업 순서를 보장하기 위해 "신선한"의 정의를 다음과 같이 변경했습니다.
fresh:
$(MAKE) clean
$(MAKE) build
이것은 기본적으로 종속성을 올바르게 지정하는 문제입니다. 트릭은 병렬 빌드가 단일 스레드 빌드보다 이에 대해 더 엄격하다는 것입니다. 내 예는 주어진 대상에 대한 종속성 목록이 반드시 실행 순서를 나타내는 것은 아님을 보여줍니다.
재귀적 make가 있는 경우 상황이 매우 쉽게 깨질 수 있습니다. 재귀적 make를 하지 않는다면 의존성이 정확하고 완전한 한 어떤 문제도 발생하지 않아야 합니다(make의 버그를 제외하고). 재귀 작성의 문제에 대한 보다 철저한 설명은 재귀 작성이 유해한 것으로 간주됨을 참조하십시오 .
모든 make 파일의 -j 옵션을 테스트하기 위해 자동화된 테스트를 갖는 것이 좋습니다. 최고의 개발자라도 make의 -j 옵션에 문제가 있습니다. 가장 일반적인 문제는 가장 간단합니다.
myrule: subrule1 subrule2
echo done
subrule1:
echo hello
subrule2:
echo world
일반적인 make에서는 hello -> world -> done이 표시됩니다. make -j 4를 사용하면 world -> hello -> done을 볼 수 있습니다.
내가 이것을 가장 많이 본 곳은 출력 디렉토리를 생성할 때입니다. 예를 들어:
build: $(DIRS) $(OBJECTS)
echo done
$(DIRS):
-@mkdir -p $@
$(OBJECTS):
$(CC) ...
효과가 명확하게 표시되지 않기 때문에 서브세트브루의 답변에 추가할 것이라고 생각했습니다. 그러나 일부 절전 명령을 추가하면 됩니다. 글쎄, 그것은 리눅스에서 작동합니다.
그런 다음 make를 실행하면 다음과의 차이점이 표시됩니다.
- 만들다
- -j4를 만들다
all: toprule1
toprule1: botrule2 subrule1 subrule2
@echo toprule 1 start
@sleep 0.01
@echo toprule 1 done
subrule1: botrule1
@echo subrule 1 start
@sleep 0.08
@echo subrule 1 done
subrule2: botrule1
@echo subrule 2 start
@sleep 0.05
@echo subrule 2 done
botrule1:
@echo botrule 1 start
@sleep 0.20
@echo "botrule 1 done (good prerequiste in sub)"
botrule2:
@echo "botrule 2 start"
@sleep 0.30
@echo "botrule 2 done (bad prerequiste in top)"
참조URL : https://stackoverflow.com/questions/1564195/gnu-makes-j-option
'IT이야기' 카테고리의 다른 글
IE8 오버플로:최대 높이가 있는 자동 (0) | 2021.09.25 |
---|---|
jpa에서 생성된 테이블의 잘못된 순서 (0) | 2021.09.25 |
HTML/JS WYSIWYG 편집기를 만드는 방법 (0) | 2021.09.24 |
날짜에 git diff (0) | 2021.09.24 |
Moq를 사용하여 전화가 올바른 순서로 이루어졌는지 확인 (0) | 2021.09.24 |