여러 코어에서 컴파일 할 때 make가 중단되는 원인은 무엇입니까?


17

어제 소스 에서 ROOT 패키지 를 컴파일하려고했습니다 . 6 코어 몬스터 머신에서 컴파일하고 있었으므로을 사용하여 여러 코어를 사용하여 빌드하기로 결정했습니다 make -j 6. 컴파일은 처음에는 매끄럽고 빨랐지만 어느 시점에서는 make하나의 코어에서 100 % CPU를 사용하여 중단되었습니다.

인터넷 검색 을 통해 ROOT 게시판 에서이 게시물을 찾았 습니다. 이 컴퓨터를 직접 만들었으므로 방열판을 제대로 적용하지 않았고 CPU가 과열 된 것 등이 걱정되었습니다. 불행히도, 나는 여기에 붙일 수있는 냉장고가 없습니다. ;-)

lm-sensors패키지를 설치하고 make -j 6이번에는 CPU 온도를 모니터링하면서 다시 실행 했습니다. 온도가 높았지만 (60 ° C에 근접) 높거나 임계 온도를 넘지 않았습니다.

나는 달리기를 시도 make -j 4했지만 make컴파일 중에 언젠가 다시 멈추었습니다. 이번에는 다른 지점에 있습니다.

결국, 나는 방금 달리기를 컴파일 make했고 잘 작동했습니다. 내 질문은 : 왜 걸려 있었습니까? 그것이 두 가지 다른 지점에서 멈췄다는 사실 때문에, 그것은 일종의 경쟁 조건 때문이라고 생각하지만 옵션을 make제공하기 때문에 모든 것을 올바른 순서로 얻을 수있을만큼 영리해야 한다고 생각 합니다 -j.


4
경쟁 조건처럼 들립니다. 당신이 할 수있는 한 가지는 예를 들어 실행중인 make 프로세스 (회전하고있는 프로세스)에 연결하고 strace -p <pid>보고 /보고있는 것을 찾을 수 있는지 확인하는 것입니다. strace는 syscall (기능 호출이 아님) 만 표시하지만 특정 파일을 보거나 검색하는 동안 회전하는 경우 여전히 유용한 정보를 제공 할 수 있습니다.
jlp

Google을 통해 찾은 스레드는 아무도 컴파일 할 수 없다는 결론을 내립니다 -j >1.
Nils

병렬 컴파일과 관련이 없지만 디버그하는 데 영원히 걸리는 교수형 makefile이 있습니다. 변수 초기화에 $(shell ...)있었으며 결국 입력을 기다리는stdin 명령을 실행하고있었습니다 . 변수가 비어 있고 파일 인수가 명령에 전달되지 않았을 때 발생합니다.
jozxyqk

답변:


13

이 정확한 문제에 대한 답은 없지만 Makefiles에서 누락 된 종속성에 대한 힌트를 줄 수 있습니다.

예:

target: a.bytecode b.bytecode
    link a.bytecode b.bytecode -o target

a.bytecode: a.source
    compile a.source -o a.bytecode

b.bytecode: b.source
    compile b.source a.bytecode -o a.bytecode

호출하면 make target모든 것이 올바르게 컴파일됩니다. 컴파일은 a.source(임의하지만 결정 론적으로) 먼저 수행됩니다. 그런 다음 컴파일 b.source이 수행됩니다.

그러나 make -j2 targetcompile명령 모두 병렬로 실행됩니다. 실제로 Makefile의 종속성이 손상되었음을 알 수 있습니다. 두 번째 컴파일 a.bytecode은 이미 컴파일 된 것으로 가정 하지만 종속성에 나타나지 않습니다. 따라서 오류가 발생할 수 있습니다. 올바른 종속성 행은 다음과 b.bytecode같아야합니다.

b.bytecode: b.source a.bytecode

운이 좋지 않은 경우 문제가 발생하면 종속성이 없어서 명령이 100 % CPU 루프에서 정지 될 수 있습니다. 그것은 아마도 여기서 일어나고있는 일이며, 누락 된 종속성은 순차적 빌드에 의해 드러날 수 없지만 병렬 빌드에 의해 드러났습니다.


흥미 롭군 makefile을 통해 실행하고 이러한 종속성을 확인할 수있는 도구가 있는지 알고 있습니까?
user545424

나도 몰라 어쨌든 그러한 도구는 명백한 실수 만 찾을 수 있습니다. Makefile에 나타나는 각 명령의 구문을 이해하고 (잠재적으로 암시적인) 종속성이 무엇인지 안다면.
Stéphane Gimenez

2

나는 당신이 기계를 얼마나 오랫동안 가지고 있었는지 모르지만, 첫 번째 권장 사항은 메모리 테스트를 시도하고 메모리가 제대로 작동하는지 확인하는 것입니다. 나는 그것이 문제의 기억이 아니라는 것을 종종 알고 있지만, 그렇다면, 아마도 다른 문제를 추적하기 전에 먼저 원인으로 제거하는 것이 가장 좋습니다.


1

나는 이것이 정말로 오래된 질문이라는 것을 알고 있지만 여전히 검색 결과의 상단에 팝업되므로 내 해결책은 다음과 같습니다.

GNU make에는 make와 그 재귀 자식이 지정된 수보다 많은 코어를 소비하지 않도록하는 작업 서버 메커니즘이 있습니다. http://make.mad-scientist.net/papers/jobserver-implementation/

모든 프로세스가 공유하는 파이프를 사용합니다. 추가 어린이를 포크하려는 각 프로세스는 먼저 파이프에서 토큰을 소비 한 다음 완료되면 토큰을 양도해야합니다. 자식 프로세스가 소비 한 토큰을 반환하지 않으면 최상위 수준의 make가 반환 될 때까지 계속 대기합니다.

https://bugzilla.redhat.com/show_bug.cgi?id=654822

"sed"가 GNU sed가 아닌 Solaris 상자에서 GNU make로 binutils를 빌드 할 때이 오류가 발생했습니다. sed == gsed가 sed 시스템보다 우선하도록 PATH를 사용하면 문제가 해결되었습니다. 그래도 sed가 파이프에서 토큰을 소비하는 이유를 모르겠습니다.


0

시스템은 괜찮을지 모르지만 make빌드를 병렬로 실행할 때 발생하는 경쟁 조건 일 수 있습니다 .

시스템에 문제가 있으면 병렬 빌드를 수행 할 때뿐만 아니라 다른 시나리오에서도 중단 / 충돌이 발생합니다.


0

경쟁 조건이 될 수 있지만 필요한 모든 컴파일이 병렬로 수행되고 다른 사람을 기다리는 경우 링크는 시스템에서 시간이 걸립니다. 링크가 이전에 필요한 컴파일을 병렬로 기다리는 경우 컴파일하는 스레드를 연결하는 데 CPU 주파수가 높아진다고 생각합니다.

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