Ninja: Heuristik: Jalankan pekerjaan dengan input besar sebelum pekerjaan dengan input kecil

Dibuat pada 15 Jul 2016  ·  14Komentar  ·  Sumber: ninja-build/ninja

Dalam LLVM build, kami memiliki beberapa file yang membutuhkan waktu lebih lama untuk dikompilasi daripada yang lain. Nama file salah satunya -- file C++ 30.000 baris (jangan tanya) -- agak terlambat menurut abjad, dan sering kali berakhir berputar lama setelah sebagian besar target lain selesai dibangun.

Akan keren jika ninja dapat, sebagai heuristik, melihat ukuran gabungan dari input aturan dan menjalankan aturan dengan input yang lebih besar terlebih dahulu.

feature

Komentar yang paling membantu

Ninja memang menghemat waktu untuk pekerjaan, jadi ia memiliki informasi itu. Build pertama mungkin tidak optimal, tetapi itu sudah terjadi karena log ninja deps juga tidak terisi.

Semua 14 komentar

Saya tidak yakin waktu kompilasi adalah fungsi unik dari ukuran file.. Saya bisa membayangkan file kecil yang sulit dipecahkan oleh kompiler, dan file besar yang sepele..

Saya tidak yakin waktu kompilasi secara unik merupakan fungsi dari ukuran file..

Ini bukan. Meskipun demikian, waktu kompilasi tentu berkorelasi positif dengan ukuran file. Demikian manfaat dari heuristik ini.

Mungkin juga ninja dapat melakukan semacam PGO (pengoptimalan terpandu profil) :+1: seperti mengumpulkan informasi waktu berapa lama waktu yang dibutuhkan untuk mengkompilasi setiap file dan menggunakan informasi ini untuk memprioritaskan file di build berikutnya.

Meskipun demikian, waktu kompilasi tentu berkorelasi positif dengan ukuran file.

Saya tidak berpikir heuristik apa pun berdasarkan file sumber akan masuk akal. Misalnya kami memiliki kurang dari seribu baris file C++ yang dikompilasi hampir satu menit (jangan tanya). Pada akhirnya itu tergantung seberapa keras file untuk preprocessor dan berapa banyak template yang akan dibuat selama kompilasi.

Tentu saja orang dapat berasumsi bahwa file 30k-line akan dikompilasi lebih lama dari 1k, tetapi menurut saya itu bukan keputusan yang harus diambil oleh ninja.

seperti mengumpulkan informasi waktu berapa lama waktu yang dibutuhkan untuk mengkompilasi setiap file ...

Ini sudah dilakukan di .ninja_log Anda dapat menggunakan skrip ini https://github.com/nico/ninjatracing untuk menguraikannya dan memuatnya di chrome untuk melihat bagaimana proses pembuatannya.

...dan gunakan informasi ini untuk memprioritaskan file di build berikutnya.

jadi karena kita sudah memiliki info build time ninja memang bisa menggunakan info itu di build selanjutnya. Benar-benar bisa membantu.

EDIT:

Ok, saya sebenarnya telah melihat waktu kompilasi. File yang dikompilasi paling lama adalah https://github.com/llvm-mirror/clang/blob/master/lib/ASTMatchers/Dynamic/Registry.cpp dan hanya memiliki 600 baris. Jadi metrik ukuran file tidak berfungsi sama sekali untuk file khusus ini.

llvm_buiild

Saya juga tidak melihat adanya hambatan dalam prosesnya. Tetapi mungkin membantu saya membangun dengan 13 utas.

Hai, jika tidak jelas, saya benar-benar bekerja di LLVM dan dentang. Saya menghabiskan beberapa minggu terakhir untuk mengoptimalkan kecepatan backend dentang/llvm, dan sebenarnya selama proses inilah saya mengalami masalah ini. Anda benar bahwa membangun kembali paket dentang dengan baik. Tetapi jika Anda menyentuh header tertentu, Anda dapat dengan mudah berakhir menunggu salah satu kompilasi yang sangat panjang ini, seperti penurunan isel x86 (yang juga muncul di akhir alfabet, memperburuk masalah).

Analisis di atas tidak bermakna secara statistik karena hanya melihat satu file. Berikut adalah sebar ukuran file cpp (sumbu x) versus waktu kompilasi (sumbu y) pada mesin saya untuk melakukan build dentang yang bersih.

Jika tidak ada korelasi antara ukuran file dan waktu kompilasi, kami berharap ini terlihat seperti noise acak. Tetapi seperti yang Anda lihat, ada korelasi yang layak antara ukuran file dan waktu kompilasi.

plt

Bagaimanapun, berpikir menggunakan waktu kompilasi sebelumnya untuk menginformasikan pemesanan adalah ide bagus.

Tentu ada korelasinya. Tapi saya tidak berpikir itu cukup konklusif untuk menjadi universal untuk setiap proyek. Saya tidak memiliki data yang tersedia, jadi saya mungkin salah di sini.

Lihat juga #60 #376 #232

Tapi saya tidak berpikir itu cukup konklusif untuk menjadi universal untuk setiap proyek.

Mungkin saya tidak jelas dengan saran saya.

Sarannya adalah, _jika Anda akan membuat pilihan sewenang-wenang antara membangun A dan B_, maka mungkin gunakan beberapa heuristik untuk mencari tahu target mana yang akan membutuhkan waktu lebih lama untuk dibangun. Heuristik "lihat berapa lama waktu yang dibutuhkan untuk membangun terakhir kali" sangat bagus, jauh lebih baik daripada saran saya untuk melihat ukuran file. Tetapi dengan tidak adanya waktu pembuatan historis, saya berharap ukuran file masih berguna.

Sekali lagi, jika heuristik yang lebih baik (seperti salah satu yang Anda sebutkan) berlaku, Anda harus menggunakannya. Tetapi karena saya hanya menyarankan agar heuristik ini diterapkan sebagai upaya terakhir, saya tidak berpikir fakta bahwa itu tidak "universal" membuat perbedaan. Kami akan membuat pilihan yang sewenang-wenang, dan sekarang kami membuat pilihan yang sedikit tidak sewenang-wenang.

Pokoknya melihat waktu pembuatan historis jauh lebih baik, saya tidak terlalu peduli jika Anda melihat ukuran file. :)

Ninja memiliki heuristik untuk membuat pilihan arbitrer antara bangunan A dan B: ia membangun mana saja yang lebih dulu dalam manifes. Bisakah Anda menempatkan heuristik Anda di generator build.ninja Anda?

@colincross Itu bagus untuk pemesanan awal, tetapi pemesanan selanjutnya dapat menggunakan waktunya agar lebih akurat daripada yang diharapkan oleh generator. Secara pribadi, saya tidak terlalu khawatir tentang waktu pembuatan awal, tetapi generator dapat mengoptimalkannya dengan cara itu.

Saya pikir menggunakan ukuran file mungkin tidak cukup untuk "profiling". Misalnya, file cpp yang sangat kecil dengan banyak penyertaan bisa sangat lama untuk diproses. Dan proses non-kompilasi (penguraian, penyalinan, pembuatan file…) tidak terkait dengan ukuran file.
Namun, itu pendekatan yang bagus untuk beberapa unit build.
Pendekatan kedua adalah dengan menghemat waktu yang diperlukan untuk membangun beberapa file dalam cache. Pembuatan ulang dapat dioptimalkan dengan menganalisis cache ini.

Ninja memang menghemat waktu untuk pekerjaan, jadi ia memiliki informasi itu. Build pertama mungkin tidak optimal, tetapi itu sudah terjadi karena log ninja deps juga tidak terisi.

@jbar ,
Saya memiliki sesuatu yang mirip dengan https://go.googlesource.com/gollvm/ : Saya mendapat beberapa ribu file sumber yang dikompilasi sebelum yang spesifik memberlakukan crash kompiler, menampilkan kesalahan "kehabisan memori".
Saat ini dua file menyebabkan kegagalan seperti itu:
https://github.com/llvm/llvm-project/blob/7d3aace3f52f6b3f87aac432aa41ae1cdeb348eb/llvm/lib/Target/AMDGPU/AMDGPULowerIntrinsics.cpp
https://github.com/llvm/llvm-project/blob/7d3aace3f52f6b3f87aac432aa41ae1cdeb348eb/llvm/lib/Target/AArch64/AArch64PreLegalizerCombiner.cpp
Sementara saya memiliki beberapa keraguan pada fakta bahwa front-end kompiler Golang ada hubungannya dengan OpenCL atau OpenGL (saat ini tidak ada acara terkait yang ada di backend) - tetapi dukungan ARM64 ada, untuk pemrograman CPU umum.
Saya harus menonaktifkan beberapa bagian dari proyek LLVM, dalam konfigurasi CMake, dalam hal apa pun.
Namun file pertama adalah 697 dari 2934 file (proses kompilasi sebelumnya mempertahankan file .o yang dikompilasi) dan yang kedua (dalam build bersih) tampaknya 817 dari 3214 file.
Akan lebih baik untuk mengkompilasi file lain terlebih dahulu, jadi saya secara prediksi akan terjebak pada file yang akan menghabiskan sebagian besar RAM saya. Jadi saya akan tertarik untuk mendapatkan yang terakhir - dan melihat mana yang bermasalah, karena saya tidak tahu itu sebelum saya mencoba. Atau bisa?

Ivan

@advancedwebdeveloper memang, ada semacam asumsi di Ninja bahwa Anda memiliki cukup RAM untuk mengkompilasi semuanya secara paralel dengan pengaturan -jN yang Anda pilih. Pada dasarnya, masalah ini bukan disebabkan oleh urutan yang dipilih Ninja, melainkan oleh fakta bahwa Ninja (dan setiap alat build lainnya yang saya ketahui) hanya memberi Anda cara yang sangat kasar untuk membatasi paralelisme -- yaitu, -j bendera.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat