GNU make: işlerin sayısı bir sistemdeki CPU çekirdek sayısına eşit mi olmalı?


88

GNU yapımındaki işlerin sayısının çekirdek sayısına eşit olup olmadığı veya diğerleri "çalışırken" sıraya alınabilecek fazladan bir iş ekleyerek derleme süresini optimize edip edemeyeceğiniz konusunda bazı tartışmalar var gibi görünüyor. .

Daha iyi kullanmak mı -j4yoksa -j5bir dört çekirdekli sistem üzerinde?

Birini veya diğerini destekleyen herhangi bir kıyaslama gördünüz mü (ya da yaptınız mı)?


8
Sadece ipucu için, make `nproc`CPU'dan bağımsız komut dosyası yapmak için kullanabilirsiniz :)
VivienG

Eğer io-bağlı ve cpu-bağımlı bir tarif karışımınız varsa, o zaman potansiyel olarak NCPU'lardan çok daha fazlasını isteyeceksiniz. Ayrıca -lX seçenekleri eklemeyi düşünün. Bu, "donanımınıza ve görevlerinize bağlıdır" dışında, gerçekten cevaplanabilir bir soru değildir.
James Moore

Teknik olarak bir gelişme görmek mümkündür. Yavaş bir diske, yeterli ram ve çok sayıda küçük kaynak kodu dosyasına ihtiyacınız var. On yıl önce gelmek daha kolay.
Hans Passant

Yanıtlar:


57

Yapılması gereken en iyi şeyin, onu kendi ortamınız ve iş yükünüze göre kıyaslamak olduğunu söyleyebilirim. Herkese uyan tek bir yanıt için çok fazla değişken var gibi görünüyor (kaynak dosyalarının boyutu / sayısı, kullanılabilir bellek, disk önbelleğe alma, kaynak dizininizin ve sistem başlıklarının farklı disklerde bulunup bulunmadığı vb.).

Kişisel deneyimim (2 çekirdekli bir MacBook Pro'da) -j2'nin -j1'den önemli ölçüde daha hızlı olduğu, ancak bunun ötesinde (-j3, -j4 vb.) Ölçülebilir bir hızlanma olmadığı. Bu yüzden çevrem için "işler == çekirdek sayısı" iyi bir cevap gibi görünüyor. (YMMV)


58

Ev projemi hyperthreading dizüstü bilgisayarımla 4 çekirdekli çalıştırdım ve sonuçları kaydettim. Bu oldukça derleyici ağırlıklı bir projedir ancak sonunda 17,7 saniyelik bir birim testi içerir. Derlemeler çok GÇ yoğun değildir; çok fazla kullanılabilir bellek var ve geri kalanı hızlı bir SSD'de.

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

Temel sonuçlar:

  • Çekirdek sayısına ölçeklendirme, performansı neredeyse doğrusal olarak artırır. Gerçek zaman 2,5 dakikadan 1,0 dakikaya (2,5 kat hızlı) düştü, ancak derleme sırasında geçen süre 2,11'den 2,50 dakikaya çıktı. Sistem, bu bitte neredeyse hiç ek yük fark etmedi.
  • Çekirdek sayısından iplik sayısına ölçeklendirme, kullanıcı yükünü 2,50 dakikadan 4,38 dakikaya büyük ölçüde artırdı. Bu neredeyse ikiye katlama, büyük olasılıkla diğer derleyici örneklerinin aynı CPU kaynaklarını aynı anda kullanmak istemesinden kaynaklanmaktadır. Sistem, istekler ve görev değiştirme ile biraz daha fazla yükleniyor ve 17,7 saniyeye ulaşmasına neden oluyor. Avantaj, 53,5 saniyelik derleme süresinde yaklaşık 6,5 saniyedir ve bu da% 12'lik bir hızlanma sağlar.
  • İş parçacığı sayısından çift iş parçacığı sayısına ölçeklendirme, önemli bir hızlanma sağlamadı. 12 ve 15'teki zamanlar büyük olasılıkla göz ardı edebileceğiniz istatistiksel anormalliklerdir. Toplam harcanan zaman, sistem zamanı kadar çok az artar. Her ikisi de büyük olasılıkla artan görev değiştirmeden kaynaklanmaktadır. Bunun bir faydası yok.

Şu anda benim tahminim: Bilgisayarınızda başka bir şey yaparsanız, çekirdek sayısını kullanın. Yapmazsanız, iplik sayısını kullanın. Bunu aşmak hiçbir fayda göstermez. Bir noktada hafıza sınırlı hale gelecekler ve bundan dolayı çökecekler, bu da derlemeyi çok daha yavaş hale getirecek. "İnf" satırı çok daha sonraki bir tarihte eklendi ve bana 8'den fazla iş için bazı termal kısıtlamalar olduğu şüphesini uyandırdı. Bu, bu proje boyutu için hiçbir bellek veya verim sınırının geçerli olmadığını gösterir. Yine de küçük bir proje, derlenecek 8 GB bellek verildi.


Stackoverflow.com/questions/56272639/… 'e göre, CPU'nuzdan daha fazla görev yürütme avantajını elde edebilirsiniz, ancak yalnızca görevleriniz ağ G / Ç'yi beklerken önemli ölçüde zaman harcıyorsa. Derleme görevleri için durum böyle değil.
ivan_pozdeev

30

Ben şahsen, make -j nn'nin "çekirdek sayısı" + 1 olduğu yerde kullanıyorum .

Ancak bilimsel bir açıklama yapamam: Aynı ayarları kullanan birçok insan gördüm ve şimdiye kadar bana oldukça iyi sonuçlar verdiler.

Her neyse, dikkatli olmalısınız çünkü bazı üretim zincirleri bu --jobsseçenekle uyumlu değildir ve beklenmedik sonuçlara yol açabilir. Garip bağımlılık hataları yaşıyorsanız, sadece makeonsuz deneyin --jobs.


19
Açıklama (bilimselliği için kefil olamaz), "+ 1" in diğer n işlerden herhangi biri G / Ç yaparken çalışan ekstra bir iş vermesidir.
Laurynas Biveinis

@LaurynasBiveinis: Ancak işler her zaman farklı çekirdeklerde çalışıyor, en azından bir işe daha uzun süre aynı çekirdekte kalma şansı verilen daha muhafazakar bir ayardan daha sık. Burada artıları ve eksileri var ...
krlmlr

1
Çekirdek sayısı + 1 benim de varsayılan ayarım. Sorunlardan biri, makul büyüklükteki herhangi bir sistemde, make'in bağlanmayı geciktirdiği ve tüm bağlantı adımlarını birlikte yaptığıdır. Bu noktada RAM'iniz biter. Bah!
bobbogo

4
bazı yapım zincirleri --jobs seçeneğiyle -> uyumlu değildir. Bu, eksik bağımlılıklarınız olduğu anlamına gelir. Bunu alırsanız makefilesinizi düzeltin.
dascandy

7

Sonuçta, yapınız için kullanılacak en iyi sayıyı belirlemek için bazı kıyaslamalar yapmanız gerekecek, ancak önemli olan tek kaynağın CPU olmadığını unutmayın!

Örneğin, büyük ölçüde diske dayanan bir yapınız varsa, o zaman çok çekirdekli bir sistemde çok sayıda iş üretmek aslında daha yavaş olabilir , çünkü diskin herkese hizmet etmek için disk kafasını ileri geri hareket ettirerek fazladan iş yapması gerekecektir farklı işler (işletim sisteminin disk önbelleğini ne kadar iyi kullandığı, disk tarafından yerel komut kuyruğu desteği vb. gibi birçok faktöre bağlı olarak).

Ve sonra hiper iş parçacığına karşı "gerçek" çekirdekleriniz var. Her hiper iş parçacığı için iş üretme işlerinden faydalanabilir veya yararlanamayabilirsiniz. Yine, öğrenmek için kıyaslamanız gerekecek.

Özellikle #cores + 1'i denediğimi söyleyemem , ancak sistemlerimizde (Intel i7 940, 4 hiper iş parçacıklı çekirdek, çok sayıda RAM ve VelociRaptor sürücüleri) ve yapımızda (dönüşümlü olarak CPU ve I olan büyük ölçekli C ++ derlemesi) / O bağlı) -j4 ve -j8 arasında çok az fark vardır. (Belki% 15 daha iyi ... ama iki kat daha iyi değil.)

Öğle yemeğine gidersem -j8 kullanırım, ancak sistemimi inşa ederken başka bir şey için kullanmak istersem, daha düşük bir sayı kullanırım. :)


1
Harika görünüyor, ama neden her seferinde +% 15'i kullanarak-j 8
sg

1
@sg: j8, orijinal yazımda anlattığım sisteme gerçekten çok zarar veriyordu ... makine hala kullanılabilirdi , ancak kesinlikle daha az duyarlıydı . Öyleyse, onu diğer görevler için etkileşimli olarak kullanmak istersem (tipik olarak başka bir kod üzerinde ve belki de ara sıra tek DLL oluşturma), etkileşimli bitler için birkaç çekirdek ayırırdım.
ijprest

@sg: Bu, daha yeni sistemlerimizde daha az sorun ... Sanırım çoğunlukla şu anda SSD kullanıyoruz. (Sanırım artık SSD'lere geçeceğimize göre tamamen CPU'ya bağlıyız ... neredeyse hiç iyileştirme olmadan tamamen bir RAM sürücüsü üzerine inşa etmeyi denedik.) Ama yine de birkaç çekirdeği boş bırakacağım ön planda basit metin düzenlemeden daha fazlasını yapmak.
ijprest

5

Foxconn M / B ve 4GB G-Skill belleğe sahip Athlon II X2 Regor proc'u aldım.

Bunun sonuna 'cat / proc / cpuinfo' ve 'free' koyuyorum, böylece diğerleri benim özelliklerimi görebilir. 4GB RAM'e sahip çift çekirdekli Athlon II x2.

uname -a on default slackware 14.0 kernel is 3.2.45.

Bir sonraki adım olan çekirdek kaynağını (linux-3.2.46) / archive4'e indirdim;

çıkardı ( tar -xjvf linux-3.2.46.tar.bz2);

dizine cd'lendi ( cd linux-3.2.46);

ve varsayılan çekirdeğin yapılandırmasını ( cp /usr/src/linux/.config .) üzerine kopyaladı ;

make oldconfig3.2.46 çekirdek yapılandırmasını hazırlamak için kullanılır ;

sonra -jX'in çeşitli büyüleriyle make çalıştırdı.

Her çalışmanın zamanlamasını zaman komutundan sonra make komutu vererek test ettim, örneğin 'time make -j2'. Her çalıştırma arasında linux-3.2.46 ağacını 'rm -rf' ve yeniden çıkardım, varsayılan /usr/src/linux/.config dizinine kopyaladım, make oldconfig çalıştırdım ve sonra 'make -jX' testimi tekrar yaptım .

sade "marka":

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

yukarıdaki gibi ancak -j2 ile

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

yukarıdaki gibi ancak -j3 ile

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

yukarıdaki gibi ancak -j4 ile

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

yukarıdaki gibi ancak -j8 ile

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

'cat / proc / cpuinfo' verimi:

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

'ücretsiz' verim:

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

1
make -jBu sistemde ne yapıyor ? Make'in yükü kontrol etmesi ve yüke bağlı olarak işlem sayısını ölçeklendirmesi beklenir.
docwhat

1
make -jiş sayısını hiç sınırlamaz. Bu, orta veya büyük ölçekli bir projede genellikle felakettir çünkü RAM tarafından desteklenenden daha fazla iş hızla çatallanır. Yüke göre kısıtlamanız gereken seçenek -l [load],-j
Matt G

5

İkisi de yanlış değil. Kendinizle ve derlediğiniz yazılımın yazarıyla barışık olmak için (yazılım düzeyinde farklı çok iş parçacıklı / tek iş parçacıklı kısıtlamalar geçerlidir), şunları kullanmanızı öneririm:

make -j`nproc`

Notlar: nprocSistemde bulunan çekirdek / iş parçacığı (modern CPU) sayısını döndürecek linux komutudur. Yukarıdaki gibi onay işaretlerinin altına yerleştirmek, sayıyı make komutuna geçirecektir.

Ek bilgi: Birinin bahsettiği gibi, yazılımı derlemek için tüm çekirdekleri / iş parçacıkları kullanmak, kutunuzu tam anlamıyla boğabilir (yanıt vermiyor) ve hatta daha az çekirdek kullanmaktan daha uzun sürebilir. Burada bir Slackware kullanıcısının yayınladığını gördüğüm gibi, çift çekirdekli CPU'ya sahipti, ancak yine de j 2'de farklı olmayı bırakan j 8'e kadar testler sağladı (CPU'nun kullanabileceği sadece 2 donanım çekirdeği). Bu nedenle, yanıt vermeyen kutuyu önlemek için şu şekilde çalıştırmanızı öneririm:

make -j`nproc --ignore=2`

Bu çıkış geçecek nprockadar makeve sonuç 2 çekirdeği çıkarılır.


3

Bir referans olarak:

Gönderen Spawning Multiple Build Jobsbölümünde LKD'de :

burada n, ortaya çıkacak iş sayısıdır. Genel uygulama, işlemci başına bir veya iki iş üretmektir. Örneğin, çift işlemcili bir makinede,

$ j4 yapmak


bozuk bağlantı, bu alıntı Robert Love'ın Linux Kernel Development'tan mı?
Behrooz

Evet, o kitaptan.
Nan Xiao

1

Deneyimlerime göre, ekstra işler eklerken bazı performans avantajları olmalı. Bunun nedeni, disk G / Ç'nin CPU'nun yanı sıra dar boğazlardan biri olmasıdır. Ancak, çekirdek sayısı ve kullanılan diskin türü ile yüksek oranda birbirine bağlı olduğu için, fazladan iş sayısına karar vermek kolay değildir.


1

Yıllar sonra, bu cevapların çoğu hala doğrudur. Bununla birlikte, biraz değişiklik oldu: Fiziksel çekirdeklerinizden daha fazla iş kullanmak artık gerçekten önemli bir hızlanma sağlıyor. Dascandy'nin tablosuna bir ek olarak, işte benim Linux üzerinde bir AMD Ryzen 5 3600X üzerinde bir proje derleme zamanlarım. (Toz Oyuncak, c6f653ac3cef03acfbc44e8f29f11e1b301f1ca2'yi taahhüt edin)

Kendinizi kontrol etmenizi öneririm, ancak başkalarından gelen girdilere göre iş sayımı için mantıksal çekirdek sayınızı kullanmanın Zen'de işe yaradığını öğrendim. Bunun yanı sıra, sistem yanıt verme yeteneğini kaybetmiş gibi görünmüyor. Bunun yeni Intel CPU'lar için de geçerli olduğunu düşünüyorum. Benim de bir SSD'ye sahip olduğumu unutmayın, bu yüzden CPU'nuzu kendiniz test etmeye değebilir.

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.)

Ubuntu 19.10 w / a Ryzen 5 3600X, Samsung 860 Evo SSD (SATA) ve 32GB RAM üzerinde yapılan testler

Son not: 3600X'e sahip diğer insanlar benden daha iyi zamanlar geçirebilir. Bu testi yaparken, CPU'nun hızını biraz düşürerek Eco modunu etkinleştirdim.


0

EVET! 3950x'imde -j32'yi çalıştırıyorum ve saatlerce derleme zamanı kazandırıyor! Derleme sırasında hiçbir fark olmadan youtube izleyebilir, internette gezinebilirim, vb. İşlemci, 1 TB 970 PRO nvme veya 1 TB Auros Gen4 nvme ve 64 GB 3200C14 ile bile her zaman sabitlenmez. Öyle olsa bile, UI açısından fark etmiyorum. Yakın gelecekte bazı büyük projelerde -j48 ile test etmeyi planlıyorum. Muhtemelen yaptığınız gibi, etkileyici bir gelişme görmenizi bekliyorum. Hala dört çekirdekli olanlar aynı kazanımları elde edemeyebilir ...

Linus'un kendisi 3970x'e yükseltildi ve en düşük dolarınıza bahse girebilirsiniz, en azından -j64 koşuyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.