GNU make: haruskah jumlah pekerjaan sama dengan jumlah inti CPU dalam suatu sistem?

88

Tampaknya ada beberapa kontroversi mengenai apakah jumlah pekerjaan di GNU make seharusnya sama dengan jumlah inti, atau jika Anda dapat mengoptimalkan waktu pembuatan dengan menambahkan satu pekerjaan tambahan yang dapat diantrekan sementara yang lain "bekerja" .

Apakah lebih baik menggunakan -j4atau -j5pada sistem quad core?

Pernahkah Anda melihat (atau melakukan) pembandingan yang mendukung satu atau lainnya?

Johan
sumber
8
Sekadar tip, Anda dapat menggunakan make `nproc`untuk membuat skrip independen CPU :)
VivienG
Jika Anda memiliki campuran resep yang terikat io dan terikat cpu, maka Anda berpotensi menginginkan lebih dari NCPU. Pertimbangkan juga untuk menambahkan opsi -lX. Ini sebenarnya bukan pertanyaan yang bisa dijawab, selain "itu tergantung pada perangkat keras Anda dan membuat tugas."
James Moore
Secara teknis mungkin untuk melihat peningkatan. Anda membutuhkan disk yang lambat, tidak cukup ram dan banyak file kode sumber kecil. Lebih mudah didapat satu dekade lalu.
Hans Passant

Jawaban:

57

Saya akan mengatakan hal terbaik untuk dilakukan adalah mengukurnya sendiri pada lingkungan dan beban kerja tertentu Anda. Sepertinya ada terlalu banyak variabel (ukuran / jumlah file sumber, memori yang tersedia, cache disk, apakah direktori sumber & header sistem Anda terletak di disk yang berbeda, dll.) Untuk jawaban satu ukuran untuk semua.

Pengalaman pribadi saya (pada MacBook Pro 2-core) adalah -j2 secara signifikan lebih cepat daripada -j1, tetapi lebih dari itu (-j3, -j4 dll.) Tidak ada peningkatan kecepatan yang dapat diukur. Jadi untuk lingkungan saya "pekerjaan == jumlah inti" sepertinya merupakan jawaban yang bagus. (YMMV)

David Gelhar
sumber
58

Saya telah menjalankan proyek rumah saya pada 4-core saya dengan laptop hyperthreading dan mencatat hasilnya. Ini adalah proyek yang cukup berat untuk kompiler tetapi mencakup pengujian unit 17,7 detik di akhir. Kompilasi tidak terlalu intensif IO; ada sangat banyak memori yang tersedia dan jika tidak, sisanya ada pada SSD yang cepat.

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

Hasil dasar:

  • Penskalaan ke jumlah inti meningkatkan kinerja hampir secara linier. Waktu nyata turun dari 2,5 menit menjadi 1,0 menit (2,5x lebih cepat), tetapi waktu yang dibutuhkan selama kompilasi naik dari 2,11 menjadi 2,50 menit. Sistem melihat hampir tidak ada beban tambahan dalam bit ini.
  • Penskalaan dari jumlah inti ke jumlah utas sangat meningkatkan beban pengguna, dari 2,50 menit menjadi 4,38 menit. Penggandaan yang hampir dua kali lipat ini kemungkinan besar karena instance kompiler lain ingin menggunakan sumber daya CPU yang sama pada waktu yang sama. Sistem menjadi sedikit lebih sarat dengan permintaan dan pengalihan tugas, menyebabkannya menghabiskan waktu 17,7 detik. Keuntungannya sekitar 6,5 detik pada waktu kompilasi 53,5 detik, menghasilkan speedup 12%.
  • Penskalaan dari jumlah thread ke jumlah thread ganda tidak memberikan kecepatan yang signifikan. Waktu pada 12 dan 15 kemungkinan besar merupakan anomali statistik yang dapat Anda abaikan. Total waktu yang dibutuhkan meningkat sedikit, seperti halnya waktu sistem. Keduanya kemungkinan besar karena peningkatan pengalihan tugas. Tidak ada manfaatnya untuk ini.

Tebakan saya sekarang: Jika Anda melakukan sesuatu yang lain di komputer Anda, gunakan jumlah inti. Jika tidak, gunakan thread count. Melebihi itu tidak menunjukkan manfaat. Pada titik tertentu mereka akan menjadi memori terbatas dan runtuh karena itu, membuat kompilasi jauh lebih lambat. Baris "inf" ditambahkan di kemudian hari, memberi saya kecurigaan bahwa ada pembatasan termal untuk 8+ pekerjaan. Hal ini menunjukkan bahwa untuk ukuran proyek ini tidak ada batasan memori atau throughput yang berlaku. Ini adalah proyek kecil, diberi memori 8GB untuk dikompilasi.

pesolek
sumber
Menurut stackoverflow.com/questions/56272639/… , Anda bisa mendapatkan keuntungan menjalankan lebih banyak tugas daripada Anda memiliki CPU tetapi hanya jika tugas Anda menghabiskan sebagian besar waktu menunggu jaringan I / O. Untuk tugas kompilasi, ini tidak terjadi.
ivan_pozdeev
30

Saya, secara pribadi, menggunakan make -j n mana n adalah "jumlah inti" + 1.

Namun, saya tidak dapat memberikan penjelasan ilmiah: Saya telah melihat banyak orang menggunakan pengaturan yang sama dan mereka memberi saya hasil yang cukup bagus sejauh ini.

Bagaimanapun, Anda harus berhati-hati karena beberapa rantai merek tidak kompatibel dengan --jobsopsi tersebut, dan dapat menyebabkan hasil yang tidak terduga. Jika Anda mengalami kesalahan ketergantungan yang aneh, coba saja maketanpa --jobs.

ereOn
sumber
19
Penjelasannya (meskipun tidak dapat menjamin keilmuannya) adalah bahwa "+1" memberikan tugas tambahan yang dijalankan sementara n pekerjaan lainnya melakukan I / O.
Laurynas Biveinis
@LaurynasBiveinis: Tapi kemudian pekerjaan berjalan pada inti yang berbeda sepanjang waktu, setidaknya lebih sering dibandingkan dengan pengaturan yang lebih konservatif di mana pekerjaan diberi kesempatan untuk tetap pada inti yang sama untuk jangka waktu yang lebih lama. Ada pro dan kontra di sini ...
krlmlr
1
Number-of-core + 1 adalah pengaturan default saya juga. Satu masalah adalah bahwa, dalam sistem yang cukup besar, membuat sepertinya menunda penautan dan melakukan semua langkah penautan secara bersamaan. Saat ini Anda kehabisan RAM. Bah!
bobbogo
4
beberapa make-chain tidak kompatibel dengan opsi --jobs -> Ini berarti Anda tidak memiliki dependensi. Perbaiki makefile Anda jika Anda pernah mendapatkannya.
keren
7

Pada akhirnya, Anda harus melakukan beberapa tolok ukur untuk menentukan angka terbaik yang akan digunakan untuk build Anda, tetapi ingat bahwa CPU bukanlah satu-satunya resource yang penting!

Jika Anda memiliki build yang sangat bergantung pada disk, misalnya, melakukan banyak pekerjaan di sistem multicore mungkin sebenarnya lebih lambat , karena disk harus melakukan pekerjaan ekstra untuk menggerakkan kepala disk maju mundur untuk melayani semua pekerjaan yang berbeda (tergantung pada banyak faktor, seperti seberapa baik OS menangani disk-cache, dukungan antrian perintah asli oleh disk, dll.).

Dan kemudian Anda memiliki inti "nyata" versus hyper-threading. Anda mungkin mendapat atau tidak mendapatkan keuntungan dari pekerjaan pemijahan untuk setiap hyper-thread. Sekali lagi, Anda harus melakukan benchmark untuk mengetahuinya.

Saya tidak bisa mengatakan saya secara khusus mencoba #cores + 1 , tetapi pada sistem kami (Intel i7 940, 4 core hyperthreaded, banyak RAM, dan drive VelociRaptor) dan build kami (build C ++ skala besar yang bergantian CPU dan saya / O terikat) ada sedikit perbedaan antara -j4 dan -j8. (Mungkin 15% lebih baik ... tapi tidak ada yang dua kali lebih baik.)

Jika saya pergi untuk makan siang, saya akan menggunakan -j8, tetapi jika saya ingin menggunakan sistem saya untuk hal lain saat sedang membangun, saya akan menggunakan angka yang lebih rendah. :)

ijprest
sumber
1
Kelihatannya bagus, tapi saya bingung mengapa Anda tidak mengambil + 15% setiap kali dengan menggunakan-j 8
sg
1
@ sg: j8 benar-benar membebani sistem yang saya jelaskan di posting asli saya ... mesin masih dapat digunakan , tetapi yang pasti kurang responsif. Jadi jika saya masih ingin menggunakannya secara interaktif untuk tugas-tugas lain (biasanya mengerjakan kode lain, dan mungkin sekali-sekali membangun DLL tunggal), saya akan memesan beberapa inti untuk bit interaktif.
ijprest
@ sg: Ini bukan masalah pada sistem kami yang lebih baru ... Saya curiga itu sebagian besar karena kami menjalankan SSD sekarang. (Saya pikir kami sepenuhnya terikat dengan CPU sekarang karena kami akan menggunakan SSD ... kami mencoba membangun sepenuhnya pada drive RAM dengan hampir tidak ada peningkatan.) Tetapi saya masih akan membiarkan beberapa core kosong jika saya melakukan apa pun selain mengedit teks sederhana di latar depan.
ijprest
5

Saya baru saja mendapatkan prosesor Athlon II X2 Regor dengan Foxconn M / B dan memori G-Skill 4 GB.

Saya meletakkan 'cat / proc / cpuinfo' dan 'free' saya di akhir ini sehingga orang lain dapat melihat spesifikasi saya. Ini adalah inti ganda Athlon II x2 dengan RAM 4GB.

uname -a on default slackware 14.0 kernel is 3.2.45.

Saya mengunduh sumber kernel langkah berikutnya (linux-3.2.46) ke / archive4;

mengekstraknya ( tar -xjvf linux-3.2.46.tar.bz2);

cd ke direktori ( cd linux-3.2.46);

dan menyalin konfigurasi kernel default di atas ( cp /usr/src/linux/.config .);

bekas make oldconfig untuk menyiapkan konfigurasi kernel 3.2.46;

lalu lari make dengan berbagai mantra -jX.

Saya menguji pengaturan waktu setiap proses dengan mengeluarkan make setelah perintah waktu, misalnya, 'time make -j2'. Di antara setiap proses, saya 'rm -rf' pohon linux-3.2.46 dan mengekstraknya kembali, menyalin /usr/src/linux/.config default ke direktori, menjalankan make oldconfig dan kemudian melakukan tes 'make -jX' lagi .

biasa "membuat":

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

seperti di atas tetapi dengan make -j2

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

seperti di atas tetapi dengan make -j3

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

seperti di atas tetapi dengan make -j4

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

seperti di atas tetapi dengan make -j8

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

'cat / proc / cpuinfo' menghasilkan:

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

hasil 'gratis':

bob@Moses:/archive4$ free
             total       used       free     shared    buffers     cached
Mem:       3991304    3834564     156740          0     519220    2515308
sloMoses
sumber
1
Apa yang baru saja make -jdilakukan pada sistem itu? Make seharusnya memeriksa beban dan menskalakan jumlah proses berdasarkan beban.
docwhat
1
make -jtidak membatasi jumlah pekerjaan sama sekali. Hal ini biasanya menjadi bencana pada proyek berukuran sedang atau besar karena lebih banyak pekerjaan yang di-fork daripada yang dapat didukung oleh RAM. Opsi yang perlu Anda batasi menurut beban adalah -l [load], sehubungan dengan-j
Matt G
5

Keduanya tidak salah. Untuk berdamai dengan diri Anda sendiri dan dengan pembuat perangkat lunak yang Anda kompilasi (batasan multi-utas / utas tunggal yang berbeda berlaku pada tingkat perangkat lunak itu sendiri), saya sarankan Anda menggunakan:

make -j`nproc`

Catatan: nprocadalah perintah linux yang akan mengembalikan jumlah inti / utas (CPU modern) yang tersedia di sistem. Menempatkannya di bawah tanda centang `seperti di atas akan meneruskan nomor tersebut ke perintah make.

Info tambahan: Seperti yang disebutkan seseorang, menggunakan semua inti / utas untuk mengompilasi perangkat lunak dapat benar-benar mencekik kotak Anda sampai hampir mati (tidak responsif) dan bahkan mungkin membutuhkan waktu lebih lama daripada menggunakan lebih sedikit inti. Seperti yang saya lihat salah satu pengguna Slackware di sini memposting dia memiliki CPU inti ganda tetapi masih memberikan pengujian hingga j 8, yang berhenti berbeda pada j 2 (hanya 2 inti perangkat keras yang dapat digunakan CPU). Jadi, untuk menghindari kotak yang tidak responsif saya sarankan Anda menjalankannya seperti ini:

make -j`nproc --ignore=2`

Ini akan meneruskan output nprocke makedan mengurangi 2 core dari hasilnya.

Lucifer Digital
sumber
3

Seperti seorang ref:

Dari Spawning Multiple Build Jobsbagian di LKD :

di mana n adalah jumlah pekerjaan yang akan muncul. Praktik yang biasa dilakukan adalah menelurkan satu atau dua pekerjaan per prosesor. Misalnya, pada mesin prosesor ganda, seseorang dapat melakukannya

$ make j4

Nan Xiao
sumber
tautan rusak, apakah ini kutipan dari Pengembangan Kernel Linux oleh Robert Love?
Behrooz
Ya, dari buku itu.
Nan Xiao
1

Dari pengalaman saya, pasti ada beberapa keuntungan kinerja saat menambah pekerjaan ekstra. Ini hanya karena disk I / O adalah salah satu leher botol selain CPU. Namun tidak mudah untuk menentukan jumlah pekerjaan tambahan karena sangat terkait dengan jumlah inti dan jenis disk yang digunakan.

Matt
sumber
1

Bertahun-tahun kemudian, sebagian besar jawaban ini masih benar. Namun, ada sedikit perubahan: Menggunakan lebih banyak pekerjaan daripada yang Anda miliki inti fisik sekarang memberikan percepatan yang benar-benar signifikan. Sebagai tambahan untuk tabel Dascandy, inilah waktu saya untuk menyusun proyek pada AMD Ryzen 5 3600X di linux. (Mainan Serbuk, lakukan c6f653ac3cef03acfbc44e8f29f11e1b301f1ca2)

Saya sarankan untuk memeriksa diri Anda sendiri, tetapi saya telah menemukan dengan masukan dari orang lain bahwa menggunakan jumlah inti logis Anda untuk jumlah pekerjaan berfungsi dengan baik di Zen. Bersamaan dengan itu, sistem tampaknya tidak kehilangan daya tanggap. Saya membayangkan ini berlaku untuk CPU Intel terbaru juga. Perhatikan bahwa saya juga memiliki SSD, jadi mungkin ada baiknya untuk menguji CPU Anda sendiri.

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

Pengujian dilakukan pada Ubuntu 19.10 w / a Ryzen 5 3600X, Samsung 860 Evo SSD (SATA), dan RAM 32GB

Catatan terakhir: Orang lain dengan 3600X mungkin mendapatkan waktu yang lebih baik daripada saya. Saat melakukan tes ini, saya mengaktifkan mode Eco, mengurangi kecepatan CPU sedikit.

moonheart08
sumber
0

IYA! Pada 3950x saya, saya menjalankan -j32 dan menghemat waktu kompilasi berjam-jam! Saya masih bisa menonton youtube, menjelajahi web, dll selama kompilasi tanpa ada perbedaan. Prosesornya tidak selalu dipatok bahkan dengan nvme 1TB 970 PRO atau 1TB Auros Gen4 nvme dan 64GB 3200C14. Meskipun demikian, saya tidak memperhatikan UI yang bijaksana. Saya berencana untuk menguji dengan -j48 dalam waktu dekat pada beberapa proyek besar yang akan datang. Saya berharap, seperti yang mungkin Anda lakukan, melihat beberapa peningkatan yang mengesankan. Mereka yang masih dengan quad-core mungkin tidak mendapatkan keuntungan yang sama ....

Linus sendiri baru saja meningkatkan ke 3970x dan Anda bisa bertaruh dolar terbawah Anda, setidaknya dia menjalankan -j64.

lazyacevw.dll
sumber