Bagaimana cara menentukan angka maksimum untuk dilewatkan ke opsi -j?

31

Saya ingin mengkompilasi secepat mungkin. Sosok pergi. Dan ingin mengotomatiskan pilihan nomor yang mengikuti -jopsi. Bagaimana saya bisa secara terprogram memilih nilai itu, misalnya dalam skrip shell?

Apakah output nprocsetara dengan jumlah utas yang saya miliki untuk dikompilasi?

make -j1 make -j16

tarabyte
sumber

Jawaban:

34

nprocmemberikan jumlah core / utas CPU yang tersedia, misalnya 8 pada CPU quad-core yang mendukung SMT dua arah.

Jumlah pekerjaan yang dapat Anda jalankan secara paralel dengan makemenggunakan -jopsi tergantung pada sejumlah faktor:

  • jumlah memori yang tersedia
  • jumlah memori yang digunakan oleh setiap makepekerjaan
  • sejauh mana makepekerjaan terikat I / O- atau CPU

make -j$(nproc) adalah tempat yang layak untuk memulai, tetapi Anda biasanya dapat menggunakan nilai yang lebih tinggi, selama Anda tidak kehabisan memori yang tersedia dan mulai meronta-ronta.

Untuk pembuatan yang sangat cepat, jika Anda memiliki cukup memori, saya sarankan menggunakan a tmpfs, dengan begitu sebagian besar pekerjaan akan terikat CPU dan make -j$(nproc)akan bekerja secepat mungkin.

Stephen Kitt
sumber
3
dan ccacheuntuk nanti membangun kembali tapi ini PL
solsTiCe
1
Apakah menggunakan sesuatu seperti paralel GNU bermanfaat di sini?
terdon
Jika saya menggunakan a tmpfs, apakah saya akan terbatas pada ukuran direktori yang selalu lebih kecil dari ukuran RAM fisik saya?
tarabyte
2
Ini bukan jawaban yang bagus, tetapi dalam semangat pertanyaan yang ketat secara terprogram menentukan nilai "j" tercepat, Anda dapat mengulangi j dari 1 ke batas atas yang masuk akal (2x nproc ??) dan membungkus merek dalam timepanggilan. Bersihkan hasilnya, busa bilas berulang - dan akhirnya menyortir nilai kali / j.
Jeff Schaller
3
@terdon No. Make adalah tentang menyelesaikan dependensi, yang berarti pekerjaan masih harus dijalankan dalam urutan tertentu. Paralel GNU tidak peduli tentang itu. Di samping catatan, memutuskan pekerjaan mana yang aman untuk dijalankan secara paralel dan mana yang tidak merupakan masalah yang sulit. Semua membuat program yang menawarkan pembangunan paralel membutuhkan waktu bertahun-tahun sampai menjadi agak bermanfaat.
lcd047
6

Sayangnya, bahkan bagian berbeda dari bangunan yang sama mungkin optimal dengan nilai faktor j yang saling bertentangan, tergantung pada apa yang sedang dibangun, bagaimana, sumber daya sistem mana yang menjadi hambatan pada saat itu, apa lagi yang terjadi pada mesin pembuat, apa yang terjadi di jaringan (jika menggunakan teknik build terdistribusi), status / lokasi / kinerja banyak sistem caching yang terlibat dalam build, dll.

Mengkompilasi 100 file C kecil mungkin lebih cepat daripada mengkompilasi satu file besar, atau sebaliknya. Membangun kode berbelit-belit kecil bisa lebih lambat daripada membuat kode lurus / linier dalam jumlah besar.

Bahkan konteks masalah build - menggunakan faktor aj dioptimalkan untuk membangun pada server khusus yang disesuaikan untuk bangunan eksklusif, non-tumpang tindih dapat menghasilkan hasil yang sangat mengecewakan ketika digunakan oleh pengembang membangun secara paralel pada server bersama yang sama (masing-masing pembangunan tersebut mungkin membutuhkan lebih banyak waktu daripada mereka semua digabungkan jika serial) atau di server dengan konfigurasi perangkat keras yang berbeda atau divirtualisasikan.

Ada juga aspek ketepatan spesifikasi bangunan. Bangun yang sangat kompleks mungkin memiliki kondisi balapan yang menyebabkan kegagalan bangun intermiten dengan tingkat kejadian yang dapat sangat bervariasi dengan peningkatan atau penurunan faktor j.

Saya bisa terus dan terus. Intinya adalah bahwa Anda harus benar mengevaluasi Anda membangun di sangat konteks Anda yang ingin faktor j dioptimalkan. Komentar @Jeff Schaller berlaku: lakukan iterate sampai Anda menemukan yang terbaik. Secara pribadi saya akan mulai dari nilai nproc, coba ke atas terlebih dahulu dan ke bawah hanya jika upaya ke atas menunjukkan degradasi langsung.

Mungkin ide yang baik untuk pertama-tama mengukur beberapa bangunan identik dalam konteks yang seharusnya identik hanya untuk mendapatkan gambaran tentang variabilitas pengukuran Anda - jika terlalu tinggi dapat membahayakan seluruh upaya pengoptimalan Anda (variabilitas 20% akan sepenuhnya melampaui peningkatan 10% / membaca degradasi dalam pencarian faktor j).

Terakhir, IMHO lebih baik menggunakan server (adaptif) jika didukung dan tersedia alih-alih faktor j tetap - ini secara konsisten memberikan kinerja pembangunan yang lebih baik di rentang konteks yang lebih luas.

Dan Cornilescu
sumber
menempatkan dengan baik tentang dependensi build yang mendasarinya. dapatkah Anda mengomentari tidak ada nomor tetap dengan -jparameter? misalmake -j
tarabyte
4
make -jakan menelurkan sebanyak mungkin pekerjaan yang dimungkinkan ketergantungan seperti bom fork ( superuser.com/questions/927836/… ); build akan merayap paling baik menghabiskan sebagian besar CPU untuk mengelola proses daripada menjalankannya ( superuser.com/questions/934685/… ) dan dalam build yang sangat paralel sistem akan kehabisan memori / swap atau pid # dan build akan gagal .
Dan Cornilescu
3

Cara paling jujur ​​adalah menggunakan nprocseperti:

make -j`nproc`

Perintah nprocakan mengembalikan jumlah core pada mesin Anda. Dengan membungkusnya dalam kutu, nprocperintah akan mengeksekusi lebih dulu, mengembalikan nomor dan nomor itu akan diteruskan make.

Anda mungkin memiliki pengalaman anekdotal di mana melakukan penghitungan inti + 1 menghasilkan waktu kompilasi yang lebih cepat. Ini lebih berkaitan dengan faktor-faktor seperti penundaan I / O, keterlambatan sumber daya lainnya dan ketersediaan kendala sumber daya lainnya.

Untuk melakukannya nproc+1, coba ini:

make -j$((`nproc`+1))
010110110101
sumber
0

Jika Anda ingin menulis makeperintah untuk menggunakan pekerja paralel sebanyak Anda punya CPU virtual, saya sarankan untuk menggunakan:

nproc | xargs -I % make -j%

Yang dapat ditulis sebagai perintah mandiri atau sebagai RUNperintah di dalam Dockerfile(karena Docker tidak mendukung perintah bersarang)

Maksym Ganenko
sumber