关于GNU make中的作业数量是否应该等于核心数量似乎存在一些争议,或者您是否可以通过添加一个可以排队等待的其他作业来优化构建时间“工作”。
在四核系统上使用-j4
或-j5
会更好吗?
您是否看过(或已完成)支持其中一种的基准测试?
答案 0 :(得分:49)
我想说最好的办法是根据您的特定环境和工作量自行进行基准测试。似乎有太多变量(源文件的大小/数量,可用内存,磁盘缓存,您的源目录和系统头是否位于不同的磁盘上等),以获得一个通用的答案。< / p>
我的个人经验(在双核MacBook Pro上)是-j2明显快于-j1,但除此之外(-j3,-j4等),没有可衡量的加速。因此,对于我的环境,“jobs ==核心数”似乎是一个很好的答案。 (YMMV)
答案 1 :(得分:47)
我在我的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的内存。
答案 2 :(得分:30)
我个人使用make -j n
,其中n是“核心数”+ 1。
无论如何,你必须要小心,因为一些make-chains只是与--jobs
选项不兼容,并且可能导致意外的结果。如果您遇到奇怪的依赖性错误,只需尝试make
而不--jobs
。
答案 3 :(得分:7)
最终,您必须做一些基准来确定用于构建的最佳数字,但请记住,CPU并不是唯一重要的资源!
例如,如果你有一个严重依赖磁盘的构建,那么在多核系统上产生大量作业可能实际上较慢,因为磁盘必须做额外的工作前后移动磁盘头以服务于所有不同的作业(取决于许多因素,例如操作系统处理磁盘缓存的程度,磁盘的本机命令排队支持等)。
然后你就拥有了“真正的”内核和超线程。您可能会或可能不会从每个超线程的产生作业中受益。再一次,你必须通过基准来找出答案。
我不能说我已经专门尝试了 #cores + 1 ,但在我们的系统上(Intel i7 940,4个超线程内核,大量RAM和VelociRaptor驱动器)和我们的构建(大规模的C ++构建,交替使用CPU和I / O),-j4和-j8之间的差别很小。 (它可能好15%......但远不及两倍好。)
如果我要去吃午饭,我会使用-j8,但是如果我想在我的系统建设时使用我的系统,我将使用较低的数字。 :)
答案 4 :(得分:4)
我刚买了一个带有Foxconn M / B和4GB G-Skill内存的Athlon II X2 Regor proc。
我把'cat / proc / cpuinfo'和'free'放在最后,以便其他人可以看到我的规格。它是双核Athlon II x2,内存为4GB。
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
);
并复制默认内核的配置(cp /usr/src/linux/.config .
);
使用make oldconfig
来准备3.2.46内核配置;
然后使用-jX的各种咒语运行make。
我通过在time命令后发出make来测试每次运行的时间,例如, 'time make -j2'。在每次运行之间我'rm -rf'linux-3.2.46树并重新提取它,将默认的/usr/src/linux/.config复制到目录中,运行make oldconfig然后再次进行'make -jX'测试
plain“make”:
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
答案 5 :(得分:3)
就像参考:
来自LKD的Spawning Multiple Build Jobs
部分:
其中n是要生成的作业数。通常的做法是每个处理器产生一个或两个作业。例如,在双处理器机器上,可能会有
$ make j4
答案 6 :(得分:1)
根据我的经验,添加额外的工作时必须有一些性能优势。 这只是因为磁盘I / O是CPU之外的瓶颈之一。但是,要确定额外作业的数量并不容易,因为它与正在使用的磁盘的核心数和类型高度相关。
答案 7 :(得分:1)
两者都没有错。为了与您自己以及所编译的软件的作者保持和平(不同的多线程/单线程限制在软件级别本身适用),建议您使用:
make -j`nproc`
注意:nproc
是linux命令,它将返回系统上可用的内核/线程数(现代CPU)。像上面一样将其放置在“ ticks”下面,会将数字传递给make命令。
其他信息:正如某人所提到的那样,使用所有内核/线程来编译软件实际上可能使您的机器濒临死亡(无响应),甚至可能比使用更少的内核还要花费更长的时间。正如我在这里看到的一个Slackware用户所发布的那样,他拥有双核CPU,但仍然提供了对j 8的测试,而在j 2时就停止了变化(只有2个硬件内核可以使用CPU)。因此,为避免无响应的框,我建议您这样运行:
make -j`nproc --ignore=2`
这会将nproc
的输出传递到make
,并从其结果中减去2个核心。
答案 8 :(得分:1)
很多年后,这些答案大部分还是正确的。但是,发生了一些变化:使用比物理核更多的工作现在确实可以显着提高速度。作为Dascandy表的附录,这是我在Linux上的AMD Ryzen 5 3600X上编译项目的时间。 (火药,提交c6f653ac3cef03acfbc44e8f29f11e1b301f1ca2)
我建议检查一下自己,但是从其他人的输入中我发现,使用逻辑核心计数进行作业计数在Zen上效果很好。除此之外,该系统似乎并没有失去响应能力。我想这也适用于最近的Intel CPU。请注意,我也有一个SSD,因此值得亲自测试一下CPU。
oslopolicy-policy-generator --namespace nova
在带有Ryzen 5 3600X,Samsung 860 Evo SSD(SATA)和32GB RAM的Ubuntu 19.10上进行的测试
最后的提示:拥有3600X的其他人可能会得到比我更好的时间。进行此测试时,我启用了Eco模式,从而稍微降低了CPU的速度。
答案 9 :(得分:0)
是的!在3950x上,我运行-j32,这样可以节省数小时的编译时间!在编译过程中,我仍然可以观看youtube,浏览网络等,没有任何区别。即使使用1TB 970 PRO nvme或1TB Auros Gen4 nvme和64GB的3200C14,处理器也不总是固定的。即使是这样,我也不会注意到UI。我计划在不久的将来使用-j48在即将进行的一些大型项目中进行测试。我希望,正如您可能所做的那样,会看到一些令人印象深刻的改进。那些仍然拥有四核的人可能不会获得相同的收益。...
Linus自己刚刚升级到3970x,您可以押底钱,他至少运行-j64。