[makefile] GNU make : 작업 수가 시스템의 CPU 코어 수와 같아야합니까?

GNU make의 작업 수가 코어 수와 같아야하는지 아니면 대기열에 추가 할 수있는 작업 하나를 추가하여 빌드 시간을 최적화 할 수 있는지, 다른 작업은 “작동”하는지에 대한 논란이있는 것 같습니다. .

더 나은 사용하는 것 -j4또는 -j5쿼드 코어 시스템에?

둘 중 하나를 지원하는 벤치마킹을 보거나 수행 했습니까?



답변

가장 좋은 방법은 특정 환경과 워크로드에서 직접 벤치마킹하는 것입니다. 하나의 크기로 모든 답변을하기에는 너무 많은 변수 (소스 파일의 크기 / 수, 사용 가능한 메모리, 디스크 캐싱, 소스 디렉토리 및 시스템 헤더가 다른 디스크에 있는지 여부 등)가있는 것 같습니다.

내 개인적인 경험 (2 코어 MacBook Pro에서)은 -j2가 -j1보다 훨씬 빠르지 만 그 이상 (-j3, -j4 등)은 측정 가능한 속도 향상이 없다는 것입니다. 따라서 내 환경에서는 “작업 == 코어 수”가 좋은 대답 인 것 같습니다. (YMMV)


답변

하이퍼 스레딩 랩톱을 사용하여 4 코어에서 홈 프로젝트를 실행하고 결과를 기록했습니다. 이것은 상당히 컴파일러가 많은 프로젝트이지만 마지막에 17.7 초의 단위 테스트를 포함합니다. 컴파일은 IO 집약적이지 않습니다. 사용 가능한 메모리가 매우 많으며 나머지는 빠른 SSD에 있습니다.

1 job        real   2m27.929s    user   2m11.352s    sys    0m11.964s
2 jobs       real   1m22.901s    user   2m13.800s    sys    0m9.532s
3 jobs       real   1m6.434s     user   2m29.024s    sys    0m10.532s
4 jobs       real   0m59.847s    user   2m50.336s    sys    0m12.656s
5 jobs       real   0m58.657s    user   3m24.384s    sys    0m14.112s
6 jobs       real   0m57.100s    user   3m51.776s    sys    0m16.128s
7 jobs       real   0m56.304s    user   4m15.500s    sys    0m16.992s
8 jobs       real   0m53.513s    user   4m38.456s    sys    0m17.724s
9 jobs       real   0m53.371s    user   4m37.344s    sys    0m17.676s
10 jobs      real   0m53.350s    user   4m37.384s    sys    0m17.752s
11 jobs      real   0m53.834s    user   4m43.644s    sys    0m18.568s
12 jobs      real   0m52.187s    user   4m32.400s    sys    0m17.476s
13 jobs      real   0m53.834s    user   4m40.900s    sys    0m17.660s
14 jobs      real   0m53.901s    user   4m37.076s    sys    0m17.408s
15 jobs      real   0m55.975s    user   4m43.588s    sys    0m18.504s
16 jobs      real   0m53.764s    user   4m40.856s    sys    0m18.244s
inf jobs     real   0m51.812s    user   4m21.200s    sys    0m16.812s

기본 결과 :

  • 코어 수로 확장하면 성능이 거의 선형 적으로 향상됩니다. 실시간은 2.5 분에서 1.0 분 (2.5 배 빠름)으로 줄었지만 컴파일 시간은 2.11 분에서 2.50 분으로 늘어났습니다. 시스템은이 비트에서 추가로드를 거의 발견하지 못했습니다.
  • 코어 수에서 스레드 수로 확장하면 사용자로드가 2.50 분에서 4.38 분으로 엄청나게 증가했습니다. 이 거의 두 배가되는 것은 다른 컴파일러 인스턴스가 동시에 동일한 CPU 리소스를 사용하기를 원했기 때문일 가능성이 높습니다. 시스템에 요청 및 작업 전환이 더 많이로드되어 사용 시간이 17.7 초로 늘어납니다. 이점은 컴파일 시간 53.5 초에서 약 6.5 초로 12 % 속도 향상을 가져옵니다.
  • 스레드 수에서 이중 스레드 수로 확장해도 속도가 크게 향상되지 않았습니다. 12와 15의 시간은 무시할 수있는 통계적 이상일 가능성이 높습니다. 소요 된 총 시간은 시스템 시간과 마찬가지로 약간 증가합니다. 둘 다 작업 전환 증가로 인한 것 같습니다. 이것에는 이점이 없습니다.

내 추측으로는 컴퓨터에서 다른 작업을 수행하는 경우 코어 수를 사용합니다. 그렇지 않은 경우 스레드 수를 사용하십시오. 그것을 초과하면 이점이 없습니다. 언젠가는 메모리가 제한되고 그로 인해 붕괴되어 컴파일 속도가 훨씬 느려집니다. “inf”라인은 훨씬 나중에 추가되어 8 개 이상의 작업에 대해 약간의 열 스로틀 링이 있다는 의혹을 받았습니다. 이것은이 프로젝트 크기에 대해 유효한 메모리 또는 처리량 제한이 없음을 보여줍니다. 그러나 컴파일 할 8GB의 메모리가 주어진 작은 프로젝트입니다.


답변

나는 개인적 make -j n으로 n이 “코어 수”+ 1 인 경우를 사용합니다.

그러나 과학적인 설명은 할 수 없습니다. 같은 설정을 사용하는 사람들을 많이 보았고 지금까지 꽤 좋은 결과를 얻었습니다.

어쨌든 일부 메이크 체인은 단순히 --jobs옵션 과 호환되지 않고 예기치 않은 결과를 초래할 수 있으므로주의해야 합니다. 이상한 종속성 오류가 발생하는 make경우 --jobs.


답변

궁극적으로 빌드에 사용할 최적의 수를 결정하기 위해 몇 가지 벤치 마크를 수행해야하지만 CPU만이 중요한 리소스가 아님을 기억하십시오!

예를 들어 디스크에 크게 의존하는 빌드가있는 경우 멀티 코어 시스템에서 많은 작업을 생성하는 것이 실제로 더 느릴 수 있습니다 . 디스크가 모든 서비스를 제공하기 위해 디스크 헤드를 앞뒤로 이동하는 추가 작업을 수행해야하기 때문입니다. 다양한 작업 (OS가 디스크 캐시를 얼마나 잘 처리하는지, 디스크의 기본 명령 대기열 지원 등과 같은 많은 요인에 따라 다름).

그리고 “실제”코어와 하이퍼 스레딩이 있습니다. 각 하이퍼 스레드에 대한 작업 생성의 이점이있을 수도 있고 그렇지 않을 수도 있습니다. 다시 한 번, 벤치 마크를 통해 알아 내야합니다.

내가 특별히 #cores + 1을 시도했다고 말할 수는 없지만 우리 시스템 (Intel i7 940, 4 개의 하이퍼 스레드 코어, 많은 RAM 및 VelociRaptor 드라이브)과 우리의 빌드 (대규모 C ++ 빌드는 CPU와 I / O 바운드) -j4와 -j8 사이에는 거의 차이가 없습니다. (아마 15 % 더 나아질 수도 있지만 …)

점심을 먹으러 나가는 경우 -j8을 사용하지만 시스템을 구축하는 동안 다른 용도로 시스템을 사용하려면 더 낮은 숫자를 사용합니다. 🙂


답변

방금 Foxconn M / B와 4GB의 G-Skill 메모리가있는 Athlon II X2 Regor 프로세서를 받았습니다.

다른 사람들이 내 사양을 볼 수 있도록이 끝에 ‘cat / proc / cpuinfo’와 ‘free’를 넣었습니다. 4GB RAM을 갖춘 듀얼 코어 Athlon II x2입니다.

uname -a on default slackware 14.0 kernel is 3.2.45.

다음 단계 커널 소스 (linux-3.2.46)를 / archive4에 다운로드했습니다.

추출 ( tar -xjvf linux-3.2.46.tar.bz2);

디렉토리 ( cd linux-3.2.46); 로 cd’d

기본 커널의 구성을 ( cp /usr/src/linux/.config .)에 복사했습니다 .

make oldconfig3.2.46 커널 구성을 준비하는 데 사용 됩니다.

그런 다음 -jX의 다양한 주문으로 make를 실행했습니다.

시간 명령 뒤에 make를 실행하여 각 실행의 타이밍을 테스트했습니다 (예 : ‘time make -j2’). 각 실행 사이에 linux-3.2.46 트리를 ‘rm -rf’하고 다시 추출하고 기본 /usr/src/linux/.config를 디렉토리에 복사하고 make oldconfig를 실행 한 다음 ‘make -jX’테스트를 다시 수행했습니다. .

일반 “만들기”:

real    51m47.510s
user    47m52.228s
sys     3m44.985s
bob@Moses:/archive4/linux-3.2.46$

위와 같지만 make -j2

real    27m3.194s
user    48m5.135s
sys     3m39.431s
bob@Moses:/archive4/linux-3.2.46$

위와 같지만 make -j3

real    27m30.203s
user    48m43.821s
sys     3m42.309s
bob@Moses:/archive4/linux-3.2.46$

위와 같지만 make -j4

real    27m32.023s
user    49m18.328s
sys     3m43.765s
bob@Moses:/archive4/linux-3.2.46$

위와 같지만 make -j8

real    28m28.112s
user    50m34.445s
sys     3m49.877s
bob@Moses:/archive4/linux-3.2.46$

‘cat / proc / cpuinfo’결과 :

bob@Moses:/archive4$ cat /proc/cpuinfo
processor       : 0
vendor_id       : AuthenticAMD
cpu family      : 16
model           : 6
model name      : AMD Athlon(tm) II X2 270 Processor
stepping        : 3
microcode       : 0x10000c8
cpu MHz         : 3399.957
cache size      : 1024 KB
physical id     : 0
siblings        : 2
core id         : 0
cpu cores       : 2
apicid          : 0
initial apicid  : 0
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 5
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmo
v pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rd
tscp lm 3dnowext 3dnow constant_tsc nonstop_tsc extd_apicid pni monitor cx16 p
opcnt lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowpre
fetch osvw ibs skinit wdt npt lbrv svm_lock nrip_save
bogomips        : 6799.91
clflush size    : 64
cache_alignment : 64
address sizes   : 48 bits physical, 48 bits virtual
power management: ts ttp tm stc 100mhzsteps hwpstate

processor       : 1
vendor_id       : AuthenticAMD
cpu family      : 16
model           : 6
model name      : AMD Athlon(tm) II X2 270 Processor
stepping        : 3
microcode       : 0x10000c8
cpu MHz         : 3399.957
cache size      : 1024 KB
physical id     : 0
siblings        : 2
core id         : 1
cpu cores       : 2
apicid          : 1
initial apicid  : 1
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 5
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmo
v pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rd
tscp lm 3dnowext 3dnow constant_tsc nonstop_tsc extd_apicid pni monitor cx16 p
opcnt lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowpre
fetch osvw ibs skinit wdt npt lbrv svm_lock nrip_save
bogomips        : 6799.94
clflush size    : 64
cache_alignment : 64
address sizes   : 48 bits physical, 48 bits virtual
power management: ts ttp tm stc 100mhzsteps hwpstate

‘무료’수익률 :

bob@Moses:/archive4$ free
             total       used       free     shared    buffers     cached
Mem:       3991304    3834564     156740          0     519220    2515308


답변

둘 다 틀리지 않았습니다. 자신과 컴파일하는 소프트웨어의 작성자와 평화를 유지하려면 (소프트웨어 수준 자체에서 다른 다중 스레드 / 단일 스레드 제한이 적용됨) 다음을 사용하는 것이 좋습니다.

make -j`nproc`

참고 : nproc시스템에서 사용 가능한 코어 / 스레드 (최신 CPU) 수를 반환하는 linux 명령입니다. 위와 같이 틱 아래에 놓으면 make 명령에 번호가 전달됩니다.

추가 정보 : 누군가가 언급했듯이 모든 코어 / 스레드를 사용하여 소프트웨어를 컴파일하면 말 그대로 상자가 거의 죽을 수 있으며 (응답하지 않음) 코어를 적게 사용하는 것보다 더 오래 걸릴 수 있습니다. 내가 여기에 게시 한 한 Slackware 사용자를 보았을 때 그는 듀얼 코어 CPU를 가지고 있었지만 여전히 최대 j 8 테스트를 제공했으며, 이는 j 2 (CPU가 사용할 수있는 하드웨어 코어 2 개만)에서 차이를 멈췄습니다. 따라서 응답하지 않는 상자를 피하기 위해 다음과 같이 실행하는 것이 좋습니다.

make -j`nproc --ignore=2`

이 출력 통과 할 nproc로를 make하고 그 결과 2 개 코어를 뺍니다.


답변

심판처럼 :

에서 Spawning Multiple Build Jobs섹션 LKD :

여기서 n은 생성 할 작업의 수입니다. 일반적인 방법은 프로세서 당 하나 또는 두 개의 작업을 생성하는 것입니다. 예를 들어, 듀얼 프로세서 시스템에서는 다음을 수행 할 수 있습니다.

$ j4 만들기