Apa yang bisa menyebabkan make untuk digantung ketika dikompilasi pada banyak core?

17

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 maketergantung 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-sensorspaket dan berlari make -j 6lagi, kali ini memonitor suhu CPU. Meskipun tinggi (mendekati 60 C), tidak pernah melewati suhu tinggi atau kritis.

Saya mencoba berlari make -j 4tetapi sekali lagi makedigantung selama kompilasi, kali ini di tempat yang berbeda.

Pada akhirnya, saya mengkompilasi hanya berjalan makedan 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 makeharus cukup pintar untuk mendapatkan semuanya dalam urutan yang benar karena ia menawarkan -jopsi.

pengguna545424
sumber
4
Itu terdengar seperti kondisi balapan. Satu hal yang bisa Anda lakukan adalah melampirkan ke proses make running (yang sedang berputar) menggunakan, misalnya 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.
jlp
Utas yang Anda temukan melalui google mengarah pada kesimpulan bahwa tidak ada yang dapat mengompilasinya -j >1.
Nils
Tidak terkait dengan kompilasi paralel, tapi saya punya makefile gantung yang membutuhkan waktu lama untuk debug. Ternyata itu hanya dalam inisialisasi variabel, $(shell ...)akhirnya menjalankan perintah yang menunggu input daristdin . Ini disebabkan ketika sebuah variabel kosong dan tidak ada argumen file yang diteruskan ke perintah.
jozxyqk

Jawaban:

13

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:

target: a.bytecode b.bytecode
    link a.bytecode b.bytecode -o target

a.bytecode: a.source
    compile a.source -o a.bytecode

b.bytecode: b.source
    compile b.source a.bytecode -o a.bytecode

Jika Anda memanggil make targetsemuanya akan dikompilasi dengan benar. Kompilasi a.sourcedilakukan (sewenang-wenang, tetapi secara deterministik) terlebih dahulu. Kemudian kompilasi b.sourcedilakukan.

Tetapi jika Anda make -j2 targetberdua compileperintah akan dijalankan secara paralel. Dan Anda akan benar-benar memperhatikan bahwa dependensi Makefile Anda rusak. Kompilasi kedua mengasumsikan a.bytecodesudah dikompilasi, tetapi tidak muncul dalam dependensi. Jadi kesalahan mungkin terjadi. Baris ketergantungan yang benar untuk b.bytecodeharus:

b.bytecode: b.source a.bytecode

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.

Stéphane Gimenez
sumber
Menarik. Apakah Anda tahu jika ada alat yang tersedia yang dapat dijalankan melalui makefile dan memeriksa dependensi ini?
user545424
Saya tidak tahu. Bagaimanapun alat seperti itu hanya dapat menemukan kesalahan yang jelas. Kecuali itu memahami sintaks untuk setiap perintah yang muncul di Makefile, dan tahu apa dependensi (berpotensi implisit).
Stéphane Gimenez
2

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.

pembunuh kulit
sumber
1

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.

Fazal Majid
sumber
0

sistem Anda mungkin baik-baik saja, tetapi itu bisa menjadi kondisi balapan yang terjadi makeketika menjalankan build secara paralel.

Jika ada yang salah dengan sistem Anda, itu akan hang / crash untuk skenario lain, tidak hanya ketika melakukan build paralel.

fduff
sumber
0

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.

MahmutBulut
sumber