Eksekusi Dinamis

Laporkan masalah Lihat sumber Nightly · 8.0 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Eksekusi dinamis adalah fitur di Bazel sejak versi 0.21, tempat eksekusi tindakan yang sama secara lokal dan jarak jauh dimulai secara paralel, menggunakan output dari cabang pertama yang selesai, membatalkan cabang lainnya. Fitur ini menggabungkan daya eksekusi dan/atau cache bersama yang besar dari sistem build jarak jauh dengan latensi rendah eksekusi lokal, sehingga memberikan yang terbaik dari kedua dunia tersebut untuk build bersih dan inkremental.

Halaman ini menjelaskan cara mengaktifkan, menyesuaikan, dan men-debug eksekusi dinamis. Jika Anda telah menyiapkan eksekusi lokal dan jarak jauh serta mencoba menyesuaikan setelan Bazel untuk performa yang lebih baik, halaman ini cocok untuk Anda. Jika Anda belum menyiapkan eksekusi jarak jauh, buka Ringkasan Eksekusi Jarak Jauh Bazel terlebih dahulu.

Mengaktifkan eksekusi dinamis?

Modul eksekusi dinamis adalah bagian dari Bazel, tetapi untuk menggunakan eksekusi dinamis, Anda harus sudah dapat mengompilasi secara lokal dan jarak jauh dari penyiapan Bazel yang sama.

Untuk mengaktifkan modul eksekusi dinamis, teruskan flag --internal_spawn_scheduler ke Bazel. Tindakan ini akan menambahkan strategi eksekusi baru yang disebut dynamic. Sekarang Anda dapat menggunakannya sebagai strategi untuk mnemoni yang ingin dijalankan secara dinamis, seperti --strategy=Javac=dynamic. Lihat bagian berikutnya untuk mengetahui cara memilih mnemoni yang akan mengaktifkan eksekusi dinamis.

Untuk setiap mnemoni yang menggunakan strategi dinamis, strategi eksekusi jarak jauh diambil dari flag --dynamic_remote_strategy, dan strategi lokal dari flag --dynamic_local_strategy. Meneruskan --dynamic_local_strategy=worker,sandboxed akan menetapkan default untuk cabang lokal eksekusi dinamis untuk dicoba dengan pekerja atau eksekusi dengan sandbox dalam urutan tersebut. Meneruskan --dynamic_local_strategy=Javac=worker akan mengganti default untuk mnemonik Javac saja. Versi jarak jauh berfungsi dengan cara yang sama. Kedua flag tersebut dapat ditentukan beberapa kali. Jika tidak dapat dieksekusi secara lokal, tindakan tersebut akan dieksekusi dari jarak jauh seperti biasa, dan sebaliknya.

Jika sistem jarak jauh Anda memiliki cache, flag --local_execution_delay akan menambahkan penundaan dalam milidetik ke eksekusi lokal setelah sistem jarak jauh menunjukkan hit cache. Hal ini menghindari eksekusi lokal saat lebih banyak hit cache yang mungkin terjadi. Nilai defaultnya adalah 1000 md, tetapi harus disesuaikan agar sedikit lebih lama dari waktu yang biasanya diperlukan cache hit. Waktu yang sebenarnya bergantung pada sistem jarak jauh dan berapa lama waktu yang diperlukan untuk perjalanan bolak-balik. Biasanya, nilainya akan sama untuk semua pengguna sistem jarak jauh tertentu, kecuali jika beberapa di antaranya cukup jauh untuk menambahkan latensi bolak-balik. Anda dapat menggunakan fitur pembuatan profil Bazel untuk melihat berapa lama hit cache standar.

Eksekusi dinamis dapat digunakan dengan strategi sandbox lokal serta dengan pekerja persisten. Pekerja persisten akan otomatis berjalan dengan sandboxing saat digunakan dengan eksekusi dinamis, dan tidak dapat menggunakan pekerja multipleks. Pada sistem Darwin dan Windows, strategi dengan sandbox dapat berjalan lambat; Anda dapat meneruskan --reuse_sandbox_directories untuk mengurangi overhead pembuatan sandbox di sistem ini.

Eksekusi dinamis juga dapat berjalan dengan strategi standalone, meskipun karena strategi standalone harus mengambil kunci output saat mulai dieksekusi, strategi ini secara efektif memblokir strategi jarak jauh agar tidak selesai terlebih dahulu. Flag --experimental_local_lockfree_output memungkinkan cara untuk mengatasi masalah ini dengan memungkinkan eksekusi lokal menulis langsung ke output, tetapi dibatalkan oleh eksekusi jarak jauh, jika selesai terlebih dahulu.

Jika salah satu cabang eksekusi dinamis selesai lebih dulu, tetapi gagal, seluruh tindakan akan gagal. Ini adalah pilihan yang disengaja untuk mencegah perbedaan antara eksekusi lokal dan jarak jauh agar tidak terlewatkan.

Untuk mengetahui latar belakang selengkapnya tentang cara kerja eksekusi dinamis dan pengunciannya, lihat postingan blog yang bagus dari Julio Merino

Kapan saya harus menggunakan eksekusi dinamis?

Eksekusi dinamis memerlukan beberapa bentuk sistem eksekusi jarak jauh. Saat ini, sistem jarak jauh khusus cache tidak dapat digunakan, karena cache yang tidak ada akan dianggap sebagai tindakan yang gagal.

Tidak semua jenis tindakan cocok untuk dieksekusi dari jarak jauh. Kandidat terbaik adalah kandidat yang secara inheren lebih cepat secara lokal, misalnya melalui penggunaan pekerja persisten, atau yang berjalan cukup cepat sehingga overhead eksekusi jarak jauh mendominasi waktu eksekusi. Karena setiap tindakan yang dijalankan secara lokal mengunci sejumlah resource CPU dan memori, menjalankan tindakan yang tidak termasuk dalam kategori tersebut hanya akan menunda eksekusi untuk tindakan yang termasuk dalam kategori tersebut.

Mulai rilis 5.0.0-pre.20210708.4, profiling performa berisi data tentang eksekusi pekerja, termasuk waktu yang dihabiskan untuk menyelesaikan permintaan pekerjaan setelah kalah dalam perlombaan eksekusi dinamis. Jika Anda melihat thread pekerja eksekusi dinamis menghabiskan waktu yang signifikan untuk memperoleh resource, atau menghabiskan banyak waktu di async-worker-finish, Anda mungkin memiliki beberapa tindakan lokal lambat yang menunda thread pekerja.

Membuat profil data dengan performa eksekusi dinamis yang buruk

Dalam profil di atas, yang menggunakan 8 pekerja Javac, kita melihat banyak pekerja Javac yang telah kalah dalam perlombaan dan menyelesaikan pekerjaan mereka di thread async-worker-finish. Hal ini disebabkan oleh mnemoni non-pekerja yang menggunakan resource yang cukup untuk menunda pekerja.

Membuat profil data dengan performa eksekusi dinamis yang lebih baik

Jika hanya Javac yang dijalankan dengan eksekusi dinamis, hanya sekitar setengah pekerja yang dimulai yang akhirnya kalah dalam perlombaan setelah memulai pekerjaannya.

Flag --experimental_spawn_scheduler yang sebelumnya direkomendasikan tidak digunakan lagi. Ini mengaktifkan eksekusi dinamis dan menetapkan dynamic sebagai strategi default untuk semua mnemoni, yang sering kali menyebabkan masalah semacam ini.

Pemecahan masalah

Masalah pada eksekusi dinamis dapat bersifat halus dan sulit di-debug, karena hanya dapat terlihat dalam beberapa kombinasi tertentu dari eksekusi lokal dan jarak jauh. --debug_spawn_scheduler menambahkan output tambahan dari sistem eksekusi dinamis yang dapat membantu men-debug masalah ini. Anda juga dapat menyesuaikan tanda --local_execution_delay dan jumlah tugas jarak jauh vs. lokal untuk mempermudah reproduksi masalah.

Jika Anda mengalami masalah dengan eksekusi dinamis menggunakan strategi standalone, coba jalankan tanpa --experimental_local_lockfree_output, atau jalankan tindakan lokal Anda dengan sandbox. Tindakan ini dapat sedikit memperlambat build Anda (lihat di atas jika Anda menggunakan Mac atau Windows), tetapi akan menghilangkan beberapa kemungkinan penyebab kegagalan.