关于GNU make中的作业数量是否应该等于内核数量,或者是否可以通过添加一个可以排队等待其他作业“工作”的额外作业来优化构建时间,似乎存在争议。 。
是在四核系统上使用-j4
还是更好-j5
?
您是否看到(或完成了)任何一个支持另一个的基准测试?
关于GNU make中的作业数量是否应该等于内核数量,或者是否可以通过添加一个可以排队等待其他作业“工作”的额外作业来优化构建时间,似乎存在争议。 。
是在四核系统上使用-j4
还是更好-j5
?
您是否看到(或完成了)任何一个支持另一个的基准测试?
Answers:
我已经在带有超线程笔记本电脑的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
基本结果:
我现在的猜测是:如果您在计算机上执行其他操作,请使用核心计数。如果没有,请使用线程数。超过它并没有显示任何好处。在某些时候,它们将变得受内存限制并因此而崩溃,从而使编译慢得多。“ inf”行是在较晚的日期添加的,这使我怀疑8个以上的作业存在一些热限制。这确实表明,对于此项目大小,没有有效的内存或吞吐量限制。不过,这是一个小项目,可以编译8GB的内存。
我个人使用make -j n
n为“核数” +1。
但是,我无法给出科学的解释:我见过很多人使用相同的设置,到目前为止,他们给了我很好的效果。
无论如何,您必须要小心,因为某些制造链与该--jobs
选件根本不兼容,并可能导致意外结果。如果您遇到奇怪的依赖错误,请尝试make
不使用--jobs
。
最终,您必须做一些基准测试来确定用于构建的最佳数量,但是请记住,CPU并不是唯一重要的资源!
例如,如果您的构建严重依赖于磁盘,那么在多核系统上产生大量作业实际上可能会比较慢,因为磁盘将不得不做一些额外的工作来回移动磁盘才能服务所有磁盘。不同的作业(取决于许多因素,例如操作系统处理磁盘缓存的性能如何,磁盘对本机命令的支持等等)。
然后,您有了“真正的”核心与超线程。您可能会也可能不会从每个超线程的生成工作中受益。同样,您必须进行基准测试才能找出答案。
我不能说我专门尝试了#cores + 1,但是在我们的系统(Intel i7个超线程内核,大量RAM和VelociRaptor驱动器)和我们的构建(大规模C ++生成,交替使用CPU和I)上/ O界)-j4和-j8之间几乎没有什么区别。(它可能好了15%……但远不及两倍。)
如果我要去吃午餐,我将使用-j8,但如果要在构建系统时将其用于其他任何系统,则将使用较小的数字。:)
-j 8
我刚刚获得了带有富士康M / B和4GB G-Skill内存的Athlon II X2 Regor proc。
我将“ cat / proc / cpuinfo”和“免费”放在此结尾,以便其他人可以看到我的规格。它是具有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进入目录(cd linux-3.2.46
);
并将默认内核的配置复制到(cp /usr/src/linux/.config .
);
用于make oldconfig
准备3.2.46内核配置;
然后用-jX的各种咒语进行make。
我通过在time命令后发出make来测试每次运行的时间,例如'time make -j2'。在每次运行之间,我对linux-3.2.46树“ rm -rf”进行重新提取,将默认的/usr/src/linux/.config复制到目录中,运行make oldconfig,然后再次进行“ make -jX”测试。
普通的“ make”:
real 51m47.510s
user 47m52.228s
sys 3m44.985s
bob@Moses:/archive4/linux-3.2.46$
如上,但使用-j2
real 27m3.194s
user 48m5.135s
sys 3m39.431s
bob@Moses:/archive4/linux-3.2.46$
如上,但用-j3
real 27m30.203s
user 48m43.821s
sys 3m42.309s
bob@Moses:/archive4/linux-3.2.46$
如上,但用-j4
real 27m32.023s
user 49m18.328s
sys 3m43.765s
bob@Moses:/archive4/linux-3.2.46$
如上,但用-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
在该系统上做什么?Make应该检查负载并根据负载缩放进程数。
make -j
完全没有限制工作的数量。对于中型或大型项目,这通常是灾难性的,因为分叉的工作快于RAM支持的工作。您需要通过负载限制的选项是-l [load]
,与-j
两者都没有错。为了与您自己以及正在编译的软件的作者保持和平(不同的多线程/单线程限制本身适用于软件级别),建议您使用:
make -j`nproc`
注意:nproc
是linux命令,它将返回系统上可用的内核/线程数(现代CPU)。像上面一样将其放在ticks之下,会将数字传递给make命令。
其他信息:正如某人所提到的那样,使用所有内核/线程来编译软件实际上可能会使您的机器几乎瘫痪(无响应),甚至可能比使用更少的内核还要花费更长的时间。正如我在这里看到的一个Slackware用户所发布的那样,他拥有双核CPU,但仍然提供了对j 8的测试,但在j 2时就停止了变化(只有2个CPU可以使用的硬件内核)。因此,为避免无响应的框,我建议您这样运行:
make -j`nproc --ignore=2`
这将传递nproc
to的输出,make
并从其结果中减去2个核心。
多年以后,这些答案中的大多数仍然是正确的。但是,发生了一些变化:使用比物理核更多的工作现在确实可以显着提高速度。作为Dascandy表的附录,这是我在Linux上的AMD Ryzen 5 3600X上编译项目的时间。(The Powder Toy,提交c6f653ac3cef03acfbc44e8f29f11e1b301f1ca2)
我建议检查一下自己,但从其他人的输入中我发现,使用逻辑核心计数进行作业计数在Zen上效果很好。除此之外,该系统似乎并没有失去响应能力。我想这也适用于最近的Intel CPU。请注意,我也有一个SSD,因此值得亲自测试一下CPU。
scons -j1 --release --native 120.68s user 9.78s system 99% cpu 2:10.60 total
scons -j2 --release --native 122.96s user 9.59s system 197% cpu 1:07.15 total
scons -j3 --release --native 125.62s user 9.75s system 292% cpu 46.291 total
scons -j4 --release --native 128.26s user 10.41s system 385% cpu 35.971 total
scons -j5 --release --native 133.73s user 10.33s system 476% cpu 30.241 total
scons -j6 --release --native 144.10s user 11.24s system 564% cpu 27.510 total
scons -j7 --release --native 153.64s user 11.61s system 653% cpu 25.297 total
scons -j8 --release --native 161.91s user 12.04s system 742% cpu 23.440 total
scons -j9 --release --native 169.09s user 12.38s system 827% cpu 21.923 total
scons -j10 --release --native 176.63s user 12.70s system 910% cpu 20.788 total
scons -j11 --release --native 184.57s user 13.18s system 989% cpu 19.976 total
scons -j12 --release --native 192.13s user 14.33s system 1055% cpu 19.553 total
scons -j13 --release --native 193.27s user 14.01s system 1052% cpu 19.698 total
scons -j14 --release --native 193.62s user 13.85s system 1076% cpu 19.270 total
scons -j15 --release --native 195.20s user 13.53s system 1056% cpu 19.755 total
scons -j16 --release --native 195.11s user 13.81s system 1060% cpu 19.692 total
( -jinf test not included, as it is not supported by scons.)
在带有Ryzen 5 3600X,Samsung 860 Evo SSD(SATA)和32GB RAM的Ubuntu 19.10上进行的测试
最后说明:拥有3600X的其他人可能会得到比我更好的时间。进行此测试时,我启用了Eco模式,从而稍微降低了CPU的速度。
make `nproc`
用来制作独立于CPU的脚本:)