make -j 옵션에 전달할 최대 수를 결정하는 방법은 무엇입니까?


31

가능한 빨리 컴파일하고 싶습니다. 그림을 이동. 그리고 -j옵션 에 따라 숫자 선택을 자동화하고 싶습니다 . 예를 들어 쉘 스크립트에서 프로그래밍 방식으로 해당 값을 선택할 수 있습니까?

nproc컴파일 할 수있는 스레드 수와 동일한 출력이 있습니까?

make -j1 make -j16

답변:


34

nproc사용 가능한 CPU 코어 / 스레드 수를 제공합니다 ( 예 : 양방향 SMT를 지원하는 쿼드 코어 CPU의 경우 8 개).

옵션 을 make사용하여 병렬로 실행할 수있는 작업 수는 -j여러 가지 요인에 따라 다릅니다.

  • 사용 가능한 메모리 양
  • make작업에서 사용하는 메모리 양
  • 있는 정도 make작업이 I / O-또는 CPU가 바인딩입니다

make -j$(nproc) 시작하기에 적당한 곳이지만 사용 가능한 메모리를 모두 사용하지 않고 스 래싱을 시작하지 않는 한 일반적으로 더 높은 값을 사용할 수 있습니다.

정말 빠른 빌드의 경우 메모리가 충분 tmpfs하면 대부분의 작업이 CPU에 바인딩 make -j$(nproc)되어 최대한 빨리 작동 하는 방식을 사용하는 것이 좋습니다 .


3
그리고 ccache나중에 다시 빌드하지만 이것은 OT입니다
solsTiCe

1
GNU 병렬과 같은 것을 사용할 가치가 있습니까?
terdon

를 사용하는 경우 tmpfs항상 실제 RAM 크기보다 작은 디렉토리 크기로 제한됩니까?
tarabyte 2018 년

2
훌륭한 대답은 아니지만 프로그래밍 방식으로 가장 빠른 "j"값을 결정하는 문제의 엄격한 정신으로 j를 1에서 적당한 상한값 (2x nproc ??)으로 루핑하고 time전화를 걸 수 있습니다. 결과를 정리하고, 헹굼 반복을 반복하고 시간 / j 값을 정렬합니다.
Jeff Schaller

3
@terdon No. Make는 종속성을 해결하는 것입니다. 즉, 특정 순서로 작업을 계속 실행해야합니다. GNU 병렬은 그 점에 신경 쓰지 않습니다. 참고로 어떤 작업이 병렬로 실행하기에 안전한지 결정하는 것은 어려운 문제입니다. 모두 병렬 빌드를 제공하는 프로그램이 다소 유용 해지기까지 몇 년이 걸렸습니다.
lcd047

6

불행히도 동일한 빌드의 다른 부분조차도 빌드중인 대상, 당시의 시스템 리소스 중 어떤 병목 현상이 발생했는지, 빌드 시스템에서 발생하는 다른 작업, 진행중인 작업에 따라 충돌하는 j 팩터 값으로 최적 일 수 있습니다. 네트워크 (분산 빌드 기술을 사용하는 경우), 빌드와 관련된 많은 캐싱 시스템의 상태 / 위치 / 성능 등

100 개의 작은 C 파일을 컴파일하면 하나의 거대한 파일을 컴파일하는 것보다 빠를 수 있습니다. 복잡하고 복잡한 코드를 작성하는 것은 대량의 직선형 / 선형 코드를 작성하는 것보다 느릴 수 있습니다.

빌드의 맥락조차도-겹치지 않는 독점 빌드에 맞게 조정 된 전용 서버의 빌드에 최적화 된 aj 팩터를 사용하면 개발자가 동일한 공유 서버에서 병렬로 빌드 할 때 매우 실망스러운 결과를 얻을 수 있습니다 (각 빌드마다 더 많은 시간이 걸릴 수 있음) 직렬화 된 경우 또는 하드웨어 구성이 다르거 나 가상화 된 서버에서 모든 시간이 결합 된 것보다 시간.

빌드 사양의 정확성 측면도 있습니다. 매우 복잡한 빌드는 j 팩터의 증가 또는 감소에 따라 크게 변할 수있는 발생률로 간헐적 인 빌드 실패를 유발하는 경쟁 조건을 가질 수 있습니다.

나는 계속 갈 수 있습니다. 요점은 j 팩터를 최적화하려는 컨텍스트 에서 실제로 빌드를 평가 해야 한다는 것 입니다. @Jeff Schaller의 의견이 적용됩니다. 가장 적합한 것을 찾을 때까지 반복하십시오. 개인적으로 나는 nproc 값에서 시작하고, 위쪽으로 시도하면 즉각적으로 저하되는 경우에만 먼저 위아래로 시도하십시오.

측정 변동성에 대한 아이디어를 얻기 위해 아마도 동일한 맥락에서 여러 개의 동일한 빌드를 먼저 측정하는 것이 좋습니다. 너무 높으면 전체 최적화 노력을 위태롭게 할 수 있습니다 (20 % 변동성은 10 % 개선 / j 인자 검색에서 열화 판독).

마지막으로, IMHO 고정 j 인자 대신 지원되고 사용 가능한 경우 (적응) 작업 서버 를 사용하는 것이 좋습니다. 광범위한 컨텍스트에서 일관되게 더 나은 빌드 성능을 제공합니다.


기본 빌드의 종속성에 대해 잘 설명하십시오. -j매개 변수로 고정 번호를 전달하지 않는 것에 대해 언급 할 수 있습니까? 예 :make -j
tarabyte

4
make -j포크 폭탄과 같이 종속성이 허용하는 한 많은 작업을 생성합니다 ( superuser.com/questions/927836/… ). 빌드는 프로세스를 실행하는 것 ( superuser.com/questions/934685/… ) 보다 프로세스 관리에 가장 많은 CPU를 소비하면서 크롤링하며 고도로 병렬 빌드 인 경우 시스템에 메모리 / 스왑 또는 pid #이 부족하여 빌드가 실패합니다. .
Dan Cornilescu

3

가장 간단한 방법은 nproc다음과 같이 사용하는 것입니다.

make -j`nproc`

이 명령 nproc은 머신의 코어 수를 반환합니다. 틱으로 래핑하면 nproc명령이 먼저 실행되고 숫자가 반환되고 해당 숫자가로 전달됩니다 make.

코어 수 + 1을 수행하면 컴파일 시간이 빨라지는 일화적인 경험이있을 수 있습니다. 이는 I / O 지연, 기타 리소스 지연 및 기타 리소스 제약 조건과 같은 요소와 관련이 있습니다.

이 작업을 수행하려면 다음을 nproc+1시도하십시오.

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

0

make가상 CPU를 보유한만큼 많은 병렬 작업자를 사용하는 명령 을 작성 하려면 다음을 사용하는 것이 좋습니다.

nproc | xargs -I % make -j%

Docker는 중첩 명령을 지원하지 않기 때문에 독립 실행 형 명령 또는 RUN지시문 으로 작성할 수 있습니다Dockerfile

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.