Pertanyaan cepat: apa tanda kompiler yang memungkinkan g ++ untuk menelurkan banyak contoh dari dirinya sendiri untuk mengkompilasi proyek besar lebih cepat (misalnya 4 file sumber sekaligus untuk CPU multi-core)?
Apakah ini akan sangat membantu? Semua pekerjaan kompilasi saya terikat I / O daripada terikat CPU.
Brian Knoblauch
5
Bahkan jika mereka terikat I / O Anda mungkin dapat menjaga beban I / O lebih tinggi ketika CPU bit berat terjadi (dengan hanya satu contoh g + + akan ada jeda) dan mungkin mendapatkan efisiensi I / O jika penjadwal memiliki lebih banyak pilihan tentang apa yang harus dibaca dari disk selanjutnya. Pengalaman saya adalah bahwa penggunaan yang bijaksana make -jhampir selalu menghasilkan beberapa perbaikan.
Flexo
1
@BrianKnoblauch Tetapi di komputer saya (yang asli atau di VirtualBox), itu terikat CPU, saya menemukan bahwa CPU sibuk melalui perintah 'top' ketika mengkompilasi.
大 宝剑
1
Bahkan jika mereka terikat I / O, kita dapat menggunakan flag '-pipa' gcc untuk mengurangi rasa sakit.
Anda -j nomor harus 1,5x jumlah inti yang Anda miliki.
Mark Beckwith
2
Terima kasih. Saya terus mencoba meneruskan "-j #" ke gcc melalui CFLAGS / CPPFLAGS / CXXFLAGS. Saya benar-benar lupa bahwa "-j #" adalah parameter untuk GNU make (dan bukan untuk GCC).
chriv
33
Mengapa opsi- j untuk GNU Make harus berukuran 1,5 x jumlah core CPU?
bitek
28
Angka 1,5 adalah karena masalah ikatan I / O yang tercatat . Ini adalah aturan praktis. Sekitar 1/3 dari pekerjaan akan menunggu untuk I / O, sehingga pekerjaan yang tersisa akan menggunakan inti yang tersedia. Angka yang lebih besar dari inti lebih baik dan Anda bahkan bisa mencapai 2x . Lihat juga: Gnu membuat -jargumen
artless noise
4
@ Jimmichaels Bisa jadi karena dependensi buruk diatur dalam proyek Anda, (target mulai membangun bahkan jika dependensinya belum siap) sehingga hanya membangun berurutan akhirnya menjadi sukses.
Antonio
42
Tidak ada bendera seperti itu, dan memiliki satu berjalan bertentangan dengan filosofi Unix memiliki setiap alat melakukan hanya satu fungsi dan melakukannya dengan baik. Proses kompiler pemijahan secara konseptual adalah tugas sistem bangun. Apa yang mungkin Anda cari adalah bendera -j (pekerjaan) untuk GNU make, a la
make -j4
Atau Anda dapat menggunakan pmake atau sistem make paralel serupa.
"Unix pedantry tidak membantu" Untung saja itu bukan kesedihan, editor anonim. Diputar kembali. Peninjau harap lebih memperhatikan apa yang Anda lakukan.
Lightness Races in Orbit
12
Orang-orang telah menyebutkan maketetapi bjamjuga mendukung konsep serupa. Menggunakan bjam -jxmenginstruksikan bjam untuk membangun hingga xperintah bersamaan.
Kami menggunakan skrip build yang sama di Windows dan Linux dan menggunakan opsi ini membagi waktu build kami di kedua platform. Bagus.
+1 untuk -lopsi penyebutan (tidak memulai pekerjaan baru kecuali semua pekerjaan sebelumnya benar-benar berakhir). Kalau tidak, tampaknya pekerjaan linker dimulai dengan tidak semua file objek dibangun (karena beberapa kompilasi masih berlangsung), sehingga pekerjaan linker gagal.
NGI
8
Jika menggunakan make, masalah dengan -j. Dari man make:
-j [jobs],--jobs[=jobs]Specifies the number of jobs (commands) to run simultaneously.If there is more than one -j option, the last one is effective.If the -j option is given without an argument, make will not limit the
number of jobs that can run simultaneously.
Dan yang paling penting, jika Anda ingin membuat skrip atau mengidentifikasi jumlah inti yang Anda miliki (tergantung pada lingkungan Anda, dan jika Anda berjalan di banyak lingkungan, ini dapat banyak berubah) Anda dapat menggunakan fungsi Python di mana-mana cpu_count():
make -j $(python3 -c 'import multiprocessing as mp; print(int(mp.cpu_count() * 1.5))')
Jika Anda bertanya mengapa 1.5saya akan mengutip suara bising pengguna dalam komentar di atas:
Angka 1,5 adalah karena masalah ikatan I / O yang tercatat. Ini adalah aturan praktis. Sekitar 1/3 dari pekerjaan akan menunggu untuk I / O, sehingga pekerjaan yang tersisa akan menggunakan inti yang tersedia. Angka yang lebih besar dari inti lebih baik dan Anda bahkan bisa mencapai 2x.
Sebagian besar pengguna Linux lebih suka yang lebih pendek: make -j`nproc` dengan nprocdi GNU Coreutils.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
Jika Anda menggunakan SSD, I / O tidak akan menjadi masalah besar. Hanya untuk membangun komentar Ciro di atas, Anda dapat melakukan ini: make -j $(( $(nproc) + 1 ))(pastikan Anda meletakkan spasi di tempat saya memilikinya)
Ed K
Saran bagus menggunakan python, pada sistem nprocyang tidak tersedia, misalnya dalam manylinux1wadah, menghemat waktu tambahan dengan menghindari menjalankan yum update/ yum install.
hoefling
7
distcc juga dapat digunakan untuk mendistribusikan kompilasi tidak hanya pada mesin saat ini, tetapi juga pada mesin lain di pertanian yang memiliki distcc diinstal.
Saya tidak yakin tentang g ++, tetapi jika Anda menggunakan GNU Make maka "make -j N" (di mana N adalah jumlah thread yang dapat dibuat buat) akan memungkinkan make untuk menjalankan pekerjaan multple g ++ secara bersamaan (begitu lama karena file tidak saling bergantung).
tidak, bukan jumlah utas! Banyak orang salah paham akan hal itu, tetapi -j Nmengatakan membuat berapa banyak proses sekaligus harus ditelurkan, bukan utas. Itulah alasan mengapa ia tidak sebagus MS cl -MT(benar-benar multithreaded).
{.} mengambil argumen input dan menghapus ekstensi
-t mencetak perintah yang sedang dijalankan untuk memberi kami gagasan tentang kemajuan
--will-cite menghapus permintaan untuk mengutip perangkat lunak jika Anda mempublikasikan hasil menggunakannya ...
parallel sangat nyaman sehingga saya bahkan dapat melakukan cap waktu sendiri:
ls | grep -E '\.c$'| parallel -t --will-cite "\
if![-f '{.}.o']||['{}'-nt '{.}.o']; then
gcc -c -o '{.}.o''{}'
fi
"
xargs -Pjuga dapat menjalankan pekerjaan secara paralel, tetapi agak kurang nyaman untuk melakukan manipulasi ekstensi atau menjalankan beberapa perintah dengannya: Memanggil beberapa perintah melalui xargs
TODO: Saya pikir saya membaca di suatu tempat bahwa kompilasi dapat dikurangi menjadi perkalian matriks, jadi mungkin juga dimungkinkan untuk mempercepat kompilasi file tunggal untuk file besar. Tetapi saya tidak dapat menemukan referensi sekarang.
make -j
hampir selalu menghasilkan beberapa perbaikan.Jawaban:
Anda dapat melakukan ini dengan make - dengan gnu make itu adalah flag -j (ini juga akan membantu pada mesin uniprocessor).
Misalnya jika Anda ingin 4 pekerjaan paralel dari make:
Anda juga dapat menjalankan gcc di dalam pipa dengan
Ini akan menyalurkan tahap kompilasi, yang juga akan membantu menjaga core tetap sibuk.
Jika Anda memiliki mesin tambahan juga tersedia, Anda mungkin memeriksa distcc , yang akan mengkompilasi juga untuk itu.
sumber
-j
argumenTidak ada bendera seperti itu, dan memiliki satu berjalan bertentangan dengan filosofi Unix memiliki setiap alat melakukan hanya satu fungsi dan melakukannya dengan baik. Proses kompiler pemijahan secara konseptual adalah tugas sistem bangun. Apa yang mungkin Anda cari adalah bendera -j (pekerjaan) untuk GNU make, a la
Atau Anda dapat menggunakan pmake atau sistem make paralel serupa.
sumber
Orang-orang telah menyebutkan
make
tetapibjam
juga mendukung konsep serupa. Menggunakanbjam -jx
menginstruksikan bjam untuk membangun hinggax
perintah bersamaan.Kami menggunakan skrip build yang sama di Windows dan Linux dan menggunakan opsi ini membagi waktu build kami di kedua platform. Bagus.
sumber
make
akan melakukan ini untukmu. Selidiki-j
dan-l
aktifkan di halaman manual. Saya tidak berpikirg++
dapat diparalelkan.sumber
-l
opsi penyebutan (tidak memulai pekerjaan baru kecuali semua pekerjaan sebelumnya benar-benar berakhir). Kalau tidak, tampaknya pekerjaan linker dimulai dengan tidak semua file objek dibangun (karena beberapa kompilasi masih berlangsung), sehingga pekerjaan linker gagal.Jika menggunakan make, masalah dengan
-j
. Dariman make
:Dan yang paling penting, jika Anda ingin membuat skrip atau mengidentifikasi jumlah inti yang Anda miliki (tergantung pada lingkungan Anda, dan jika Anda berjalan di banyak lingkungan, ini dapat banyak berubah) Anda dapat menggunakan fungsi Python di mana-mana
cpu_count()
:https://docs.python.org/3/library/multiprocessing.html#multiprocessing.cpu_count
Seperti ini:
Jika Anda bertanya mengapa
1.5
saya akan mengutip suara bising pengguna dalam komentar di atas:sumber
make -j`nproc`
dengannproc
di GNU Coreutils.make -j $(( $(nproc) + 1 ))
(pastikan Anda meletakkan spasi di tempat saya memilikinya)nproc
yang tidak tersedia, misalnya dalammanylinux1
wadah, menghemat waktu tambahan dengan menghindari menjalankanyum update
/yum install
.distcc juga dapat digunakan untuk mendistribusikan kompilasi tidak hanya pada mesin saat ini, tetapi juga pada mesin lain di pertanian yang memiliki distcc diinstal.
sumber
Saya tidak yakin tentang g ++, tetapi jika Anda menggunakan GNU Make maka "make -j N" (di mana N adalah jumlah thread yang dapat dibuat buat) akan memungkinkan make untuk menjalankan pekerjaan multple g ++ secara bersamaan (begitu lama karena file tidak saling bergantung).
sumber
-j N
mengatakan membuat berapa banyak proses sekaligus harus ditelurkan, bukan utas. Itulah alasan mengapa ia tidak sebagus MScl -MT
(benar-benar multithreaded).GNU paralel
Saya membuat tolok ukur kompilasi sintetis dan tidak mau repot untuk membuat Makefile, jadi saya menggunakan:
Penjelasan:
{.}
mengambil argumen input dan menghapus ekstensi-t
mencetak perintah yang sedang dijalankan untuk memberi kami gagasan tentang kemajuan--will-cite
menghapus permintaan untuk mengutip perangkat lunak jika Anda mempublikasikan hasil menggunakannya ...parallel
sangat nyaman sehingga saya bahkan dapat melakukan cap waktu sendiri:xargs -P
juga dapat menjalankan pekerjaan secara paralel, tetapi agak kurang nyaman untuk melakukan manipulasi ekstensi atau menjalankan beberapa perintah dengannya: Memanggil beberapa perintah melalui xargsPenautan paralel ditanyakan di: Dapatkah gcc menggunakan banyak inti saat menautkan?
TODO: Saya pikir saya membaca di suatu tempat bahwa kompilasi dapat dikurangi menjadi perkalian matriks, jadi mungkin juga dimungkinkan untuk mempercepat kompilasi file tunggal untuk file besar. Tetapi saya tidak dapat menemukan referensi sekarang.
Diuji di Ubuntu 18.10.
sumber