Kemarin saya mencoba mengkompilasi paket ROOT dari sumber. Karena saya mengkompilasinya pada mesin monster 6 inti, saya memutuskan untuk terus maju dan membangun menggunakan banyak core make -j 6
. Proses kompilasi berjalan mulus dan sangat cepat pada awalnya, tetapi pada beberapa titik make
tergantung menggunakan CPU 100% hanya pada satu inti.
Saya melakukan beberapa googling dan menemukan posting ini di papan pesan ROOT. Karena saya membangun komputer ini sendiri, saya khawatir bahwa saya belum menerapkan heatsink dengan benar dan CPU terlalu panas atau semacamnya. Sayangnya, saya tidak punya lemari es di sini di tempat kerja sehingga saya bisa memasukkannya. ;-)
Saya menginstal lm-sensors
paket dan berlari make -j 6
lagi, kali ini memonitor suhu CPU. Meskipun tinggi (mendekati 60 C), tidak pernah melewati suhu tinggi atau kritis.
Saya mencoba berlari make -j 4
tetapi sekali lagi make
digantung selama kompilasi, kali ini di tempat yang berbeda.
Pada akhirnya, saya mengkompilasi hanya berjalan make
dan bekerja dengan baik. Pertanyaan saya adalah: Mengapa menggantung? Karena fakta bahwa itu berhenti di dua tempat yang berbeda, saya kira itu karena semacam kondisi balapan, tetapi saya akan berpikir make
harus cukup pintar untuk mendapatkan semuanya dalam urutan yang benar karena ia menawarkan -j
opsi.
strace -p <pid>
dan lihat apakah Anda bisa mencari tahu apa yang sedang dilihat / untuk. strace hanya akan menampilkan syscalls (bukan panggilan fungsi), tetapi itu masih bisa memberi Anda informasi berharga jika itu berputar sambil melihat atau mencari file tertentu.-j >1
.$(shell ...)
akhirnya menjalankan perintah yang menunggu input daristdin
. Ini disebabkan ketika sebuah variabel kosong dan tidak ada argumen file yang diteruskan ke perintah.Jawaban:
Saya tidak punya jawaban untuk masalah yang tepat ini, tetapi saya dapat mencoba memberi Anda petunjuk tentang apa yang mungkin terjadi: Ketergantungan yang hilang di Makefiles.
Contoh:
Jika Anda memanggil
make target
semuanya akan dikompilasi dengan benar. Kompilasia.source
dilakukan (sewenang-wenang, tetapi secara deterministik) terlebih dahulu. Kemudian kompilasib.source
dilakukan.Tetapi jika Anda
make -j2 target
berduacompile
perintah akan dijalankan secara paralel. Dan Anda akan benar-benar memperhatikan bahwa dependensi Makefile Anda rusak. Kompilasi kedua mengasumsikana.bytecode
sudah dikompilasi, tetapi tidak muncul dalam dependensi. Jadi kesalahan mungkin terjadi. Baris ketergantungan yang benar untukb.bytecode
harus:Untuk kembali ke masalah Anda, jika Anda tidak beruntung mungkin ada perintah yang menggantung di 100% CPU loop, karena ketergantungan yang hilang. Mungkin itulah yang terjadi di sini, ketergantungan yang hilang tidak dapat diungkapkan oleh build berurutan, tetapi itu telah diungkapkan oleh build paralel Anda.
sumber
Saya tidak tahu berapa lama Anda memiliki mesin, tetapi rekomendasi pertama saya adalah untuk mencoba tes memori dan memverifikasi bahwa memori berfungsi dengan baik. Saya tahu itu seringkali bukan ingatan yang menjadi masalah, tetapi jika ya, yang terbaik adalah menghilangkannya sebagai penyebab terlebih dahulu sebelum mencoba melacak masalah-masalah lain yang mungkin.
sumber
Saya menyadari ini adalah pertanyaan yang sangat lama, tetapi masih muncul di bagian atas hasil pencarian, jadi di sini adalah solusi saya:
GNU make memiliki mekanisme pemberi kerja untuk memastikan merek dan anak-anak rekursifnya tidak mengkonsumsi lebih dari jumlah inti yang ditentukan: http://make.mad-scientist.net/papers/jobserver-implementation/
Itu bergantung pada pipa yang digunakan bersama oleh semua proses. Setiap proses yang ingin bercabang anak-anak tambahan harus terlebih dahulu mengkonsumsi token dari pipa, kemudian melepaskan mereka ketika selesai. Jika sebuah proses anak tidak mengembalikan token yang dikonsumsinya, tingkat atas membuat sambil menggantung selamanya menunggu mereka dikembalikan.
https://bugzilla.redhat.com/show_bug.cgi?id=654822
Saya mengalami kesalahan ini ketika membuat binutils dengan GNU make di kotak Solaris saya, di mana "sed" bukan GNU sed. Mengotak-atik PATH untuk membuat sed == gsed mengambil prioritas di atas sistem dan memperbaiki masalah. Saya tidak tahu mengapa sed mengkonsumsi token dari pipa.
sumber
sistem Anda mungkin baik-baik saja, tetapi itu bisa menjadi kondisi balapan yang terjadi
make
ketika menjalankan build secara paralel.Jika ada yang salah dengan sistem Anda, itu akan hang / crash untuk skenario lain, tidak hanya ketika melakukan build paralel.
sumber
Ini bisa menjadi kondisi balapan, tetapi juga jika semua kompilasi yang diperlukan dilakukan secara paralel dan menunggu orang lain, menghubungkan membutuhkan waktu di mesin Anda. Saya pikir jika menautkan menunggu kompilasi yang diperlukan sebelumnya secara paralel, maka Anda mendapatkan frekuensi cpu tinggi pada menautkan utas apa pun yang Anda kompilasi.
sumber