Makefile

Younghwan Cha·2023년 5월 30일
0
post-thumbnail

Make


make -j
make -j $(($(nproc) + 1)) 

make 명령어의 -j 옵션을 인수없이 실행할 경우(make -j) make 는 동시에 실행할 수 있는 작업의 수를 제한하지 않고 시스템의 모든 가능한 프로세서를 병렬로 실행하게 된다. 이는 곧 make -j $(nproc) 과 같은 의미로 해석 할 수 있다.

보통의 경우에는 최적화를 이유로 make -j $(($(nproc) + 1)) 를 많이 사용한다.
여기에, $(($(nproc) + 1)) 은 사용 가능한 프로세서 수에 1을 더한 값으로, 가능한 모든 프로세서에 +1 을 더한 값의 프로세서를 사용하여 병렬로 빌드 작업을 수행하도록 지시하여 빌드를 가속화하여 빌드 시간을 단축시킨다.

그렇다면 왜 $(nproc) 이 아닌 $(nproc) + 1 만큼의 프로세서를 사용하도록 할까?

실제로 make -j $(($(nproc) + 1)) 을 사용하여 프로세서 수보다 하나 더 많은 작업을 동시에 실행하는 이유는 최적화와 관련이 있다.
빌드 작업은 종종 입출력(I/O) 작업에 의해 제한될 수 있는 데, 디스크에서 파일을 읽고 쓰는 작업이나 네트워크 작업과 같은 I/O 작업은 프로세서보다 상대적으로 느릴 수 있다.
따라서, 모든 프로세서가 빌드 작업에 참여하는 경우, I/O 작업으로 인해 일부 프로세서가 유휴 상태에 있을 수 있다. 이러한 경우에, 하나의 추가 작업을 실행하면 I/O 작업을 처리하는 동안 유휴 상태에 있는 프로세서를 활용하여 전체 빌드 속도를 향상시킬 수 있다.

그럼 +2, +3 을 하는게 성능에 더 좋은거 아닌가?

일반적으로, make -j $(($(nproc) + 1)) 에서 $(nproc) 값에 1을 더하는 것은 병렬 빌드 성능을 향상시키는 데 도움이 되지만,
$(nproc) 값을 더 큰 값(예: +2, +3)으로 설정하는 것이 항상 더 나은 성능을 제공하는 것은 아니다.
추가 프로세서를 사용하여 병렬 빌드 성능을 향상시키는 방법에는 한계가 있기 때문에 실제로 사용 가능한 프로세서 수보다 많은 작업을 동시에 실행하면, 작업 간 경쟁이 발생하거나 시스템 리소스를 과도하게 사용해 오히려 성능이 저하될 수 있다.

결론적으로, 실제 성능 향상 정도는 작업의 특성과 시스템 구성에 따라 달라질 수 있기 때문에 최상의 성능을 위해서는 실험과 최적화를 통해 적절한 값을 결정해야 한다.

$(MAKE)

아래에서 test1, test2 를 build 하려면 make -j test 를 실행하면 된다.

...
test: test1 test2

test1:
	echo test
    $(MAKE) -j $(nproc) install
    
test2:
	echo test
    $(MAKE) -j $(nproc) install

"$(MAKE)"는 makefile에서 사용되는 특별한 변수로, make 자체를 재귀적으로 호출하는 데 사용된다.

재귀 호출?
make는 makefile을 처리할 때, 내부적으로 다른 makefile을 호출할 수 있는데, 이를 재귀 호출이라고 한다.

$(MAKE) 변수는 현재 실행 중인 make 프로세스를 참조하는데 사용되는데, makefile에서 $(MAKE)를 사용하면 현재 실행 중인 make 프로세스를 재귀적으로 호출할 수 있다. 이러한 재귀 호출은 makefile에서 서브 디렉토리를 처리하거나 다른 makefile을 포함할 때 유용하다.
예를 들어, 하위 디렉토리에 있는 별도의 makefile을 호출하여 각각 독립적인 작업을 수행하고, 결과를 취합할 수 있다.

[makefile] http://doc.kldp.org/KoreanDoc/html/GNU-Make/GNU-Make-4.html

= vs :=

= : recursive assignment
:=: simple assignment

다음 코드를 보자

# Makefile

T=A
W=${T}
T=B

run:
        echo ${T}
        echo ${W}

결과는 어떻게 나올까?

$ make run
> echo B
B
echo B
B

무언가 우리가 원했던 결과가 아닌 것 같다.
makefile 안에서 = 는 코드상에서 변수를 마주칠 때 마다 새롭게 할당된다.
그렇다면 실제 변수를 마주한 최초 시점의 변수를 할당하려면 어떻게 해야할까?
이에 대한 대안이 := 이다. 아래 코드를 확인해보자.

T=A
W:=${T}
T=B

run:
        echo ${T}
        echo ${W}

==========

$ make run
> echo B
B
echo A
A

[=, :=, ?=, +=] https://stackoverflow.com/questions/4879592/whats-the-difference-between-and-in-makefile
[=, :=, +=] https://leehc257.tistory.com/67

profile
개발 기록

0개의 댓글