다중 코어를 사용하여 g ++로 컴파일


174

빠른 질문 : g ++이 큰 프로젝트를 더 빨리 컴파일하기 위해 g ++가 여러 인스턴스를 생성 할 수있게 해주는 컴파일러 플래그는 무엇입니까 (예 : 멀티 코어 CPU의 경우 한 번에 4 개의 소스 파일)?


정말 도움이 되나요? 모든 컴파일 작업은 CPU 바운드가 아니라 I / O 바운드입니다.
Brian Knoblauch

5
그것들이 I / O 바운드 인 경우에도 CPU 헤비 비트가 발생할 때 I / O로드를 더 높게 유지할 수 있으며 (g ++ 인스턴스가 하나만 있으면 멈춤) 스케줄러가 더 많은 선택을 할 경우 I / O 효율성을 얻을 수 있습니다 다음 디스크에서 읽을 내용. 나의 경험은 make -j거의 항상 신중하게 사용 하면 약간의 향상을 가져온다는 것입니다.
Flexo

1
@BrianKnoblauch 그러나 내 컴퓨터 (실제 또는 VirtualBox)에서 CPU가 바운드되어있어 컴파일 할 때 'top'명령을 통해 CPU가 사용 중임을 알았습니다.
大 宝剑

1
그것들이 I / O에 구속되어 있더라도 gcc의 플래그 '-pipe'를 사용하여 고통을 줄일 수 있습니다.
大 宝剑

방금 구글에서 이것을 보았습니다 : gcc.gnu.org/onlinedocs/libstdc++/manual/…
Jim Michaels

답변:


240

make-gnu make로 -j 플래그를 사용하여이를 수행 할 수 있습니다 (단일 프로세서 시스템에서도 도움이 됨).

예를 들어 make에서 4 개의 병렬 작업을 원할 경우 :

make -j 4

파이프를 사용하여 gcc를 실행할 수도 있습니다.

gcc -pipe

이것은 컴파일 단계를 파이프 라인으로 만들어 코어를 바쁘게 유지하는 데 도움이됩니다.

사용 가능한 추가 머신이있는 경우 distcc를 체크 아웃 할 수도 있습니다.


36
-j 수는 코어 수의 1.5 배 여야합니다.
Mark Beckwith with

2
감사. CFLAGS / CPPFLAGS / CXXFLAGS를 통해 "-j #"을 gcc로 전달하려고했습니다. "-j #"가 GNU make의 매개 변수 (GCC가 아닌)라는 것을 완전히 잊었습니다.
chriv

33
GNU Make 의 -j 옵션이 CPU 코어 수의 1.5 배 여야 하는 이유는 무엇 입니까?
bitek

28
1.5 숫자 때문에이 지적입니다 I를 / O 바운드 문제. 경험의 법칙입니다. 작업의 약 1/3이 I / O를 기다리고 있으므로 나머지 작업은 사용 가능한 코어를 사용합니다. 코어보다 큰 숫자가 더 좋으며 2 배 까지 올라갈 수도 있습니다. 또한보십시오 : Gnu는 -j논쟁을합니다
예술가없는 소음

4
@JimMichaels 프로젝트 내에서 종속성이 잘못 설정되어 있기 때문에 (종속성이 아직 준비되지 않은 경우 대상이 빌드를 시작하므로) 순차 빌드 만 성공합니다.
Antonio

42

이러한 플래그는 없으며 각 도구가 하나의 기능 만 수행하고 잘 수행한다는 유닉스 철학에 맞서 실행됩니다. 컴파일러 프로세스 생성은 개념적으로 빌드 시스템의 역할입니다. 아마도 찾고있는 것은 GNU make에 대한 -j (jobs) 플래그입니다.

-j4를 만든다

또는 pmake 또는 유사한 병렬 make 시스템을 사용할 수 있습니다.



3
"Unix pedantry는 도움이되지 않습니다." 그렇다면 익명 편집자 인 pedantry가 아니 었습니다. 복구하다. 검토자는 수행중인 작업에 더 많은주의를 기울이십시오.
궤도에서 가벼움 경주

12

사람들은 언급 make했지만 bjam유사한 개념을 지원합니다. 를 사용하면 bjam -jxbjam에 x동시 명령 을 작성하도록 지시 합니다.

Windows 및 Linux에서 동일한 빌드 스크립트를 사용하며이 옵션을 사용하면 두 플랫폼 모두에서 빌드 시간이 절반으로 줄어 듭니다. 좋은.


9

make당신을 위해 이것을 할 것입니다. 매뉴얼 페이지에서 -j-l스위치를 조사 하십시오. 나는 g++병렬화 할 수 없다고 생각 합니다.


-l옵션 을 언급 한 경우 +1 (이전 작업이 모두 종료되지 않으면 새 작업을 시작하지 않음) 그렇지 않으면 링커 작업이 빌드 된 모든 오브젝트 파일 (일부 컴파일이 여전히 진행 중임)로 시작하지 않아 링커 작업이 실패하는 것 같습니다.
NGI

8

make를 사용하는 경우으로 문제를 해결하십시오 -j. 보낸 사람 man make:

  -j [jobs], --jobs[=jobs]
       Specifies the number of jobs (commands) to run simultaneously.  
       If there is more than one -j option, the last one is effective.
       If the -j option is given without an argument, make will not limit the
       number of jobs that can run simultaneously.

가장 주목할 만하게, (사용 환경에 따라 사용 가능한 코어 수를 스크립팅하거나 식별하려면 많은 환경에서 실행하면 많이 변경 될 수 있음) 유비쿼터스 파이썬 함수를 사용할 수 있습니다 cpu_count().

https://docs.python.org/3/library/multiprocessing.html#multiprocessing.cpu_count

이처럼 :

make -j $(python3 -c 'import multiprocessing as mp; print(int(mp.cpu_count() * 1.5))')

1.5위의 주석에서 사용자 에게 무소음을 인용하는 이유를 묻는다면 :

1.5 숫자는 명시된 I / O 바운드 문제 때문입니다. 경험의 법칙입니다. 작업의 약 1/3이 I / O를 기다리고 있으므로 나머지 작업은 사용 가능한 코어를 사용합니다. 코어보다 큰 숫자가 더 좋으며 2 배까지 올라갈 수도 있습니다.


5
대부분의 리눅스 사용자는 가능성이 짧아을 선호하는 것 make -j`nproc` nprocGNU로 coreutils에.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

SSD를 사용하는 경우 I / O는 큰 문제가되지 않습니다. 위의 Ciro의 의견을 바탕으로 다음과 같이 할 수 있습니다. make -j $(( $(nproc) + 1 ))(공백이있는 곳에 공백을 두십시오).
Ed K

시스템에 파이썬을 사용하여 멋진 제안, nproc사용할 수 없습니다가, 예를 들면에 manylinux1용기, 그것은 실행 방지하여 추가 시간을 절약 yum update/을 yum install.
회랑


3

g ++에 대해서는 잘 모르겠지만 GNU Make를 사용하는 경우 "make -j N"(여기서 N은 만들 수있는 스레드 수)은 여러 g ++ 작업을 동시에 실행할 수있게합니다 파일이 서로 의존하지 않기 때문에).


2
아니오 N은 스레드 수가 아닙니다! 많은 사람들이 그것을 오해하지만 -j N스레드가 아니라 한 번에 몇 개의 프로세스를 생성해야하는지 알려줍니다. 그것이 MS cl -MT(실제로 멀티 스레드) 만큼 성능이 좋지 않은 이유 입니다.
Sebi2020 2016 년

2

GNU 병렬

나는 합성 컴파일 벤치 마크를 만들고 있었고 Makefile을 작성하는 데 신경 쓰지 못했습니다.

sudo apt-get install parallel
ls | grep -E '\.c$' | parallel -t --will-cite "gcc -c -o '{.}.o' '{}'"

설명:

  • {.} 입력 인수를 받아서 확장을 제거합니다
  • -t 진행 상황을 알려주기 위해 실행중인 명령을 인쇄합니다.
  • --will-cite 소프트웨어를 사용하여 결과를 게시하는 경우 소프트웨어 인용 요청을 제거합니다 ...

parallel 타임 스탬프 확인을 스스로 할 수 있도록 매우 편리합니다.

ls | grep -E '\.c$' | parallel -t --will-cite "\
  if ! [ -f '{.}.o' ] || [ '{}' -nt '{.}.o' ]; then
    gcc -c -o '{.}.o' '{}'
  fi
"

xargs -P작업을 병렬로 실행할 수도 있지만 확장 조작을 수행하거나 여러 명령을 실행하는 것이 약간 덜 편리합니다. xargs를 통해 여러 명령 호출

병렬 연결 요청 : gcc는 연결시 여러 개의 코어를 사용할 수 있습니까?

TODO : 컴파일을 행렬 곱셈으로 줄일 수있는 곳을 읽었으므로 큰 파일의 단일 파일 컴파일 속도를 높일 수도 있습니다. 하지만 지금은 참조를 찾을 수 없습니다.

우분투에서 테스트 18.10.

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