Makro likely
dan unlikely
makro sering dikenal membantu kompiler mengetahui apakah suatu if
biasanya akan dimasukkan atau dilewati. Menggunakannya menghasilkan beberapa peningkatan kinerja (agak kecil).
Saya mulai menggunakannya baru-baru ini, dan saya tidak yakin seberapa sering petunjuk seperti itu digunakan. Saat ini saya menggunakannya dengan pengecekan kesalahan if
, yang biasanya ditandai sebagai unlikely
. Sebagai contoh:
mem = malloc(size);
if (unlikely(mem == NULL))
goto exit_no_mem;
Tampaknya baik-baik saja, tetapi pengecekan kesalahan if
terjadi cukup sering dan akibatnya penggunaan makro tersebut.
Pertanyaan saya adalah, apakah terlalu banyak untuk dimiliki likely
dan unlikely
makro pada setiap pemeriksaan kesalahan if
?
Sementara kita berada di sana, tempat lain apa yang sering mereka gunakan?
Dalam penggunaan saya saat ini di perpustakaan yang membuat abstraksi dari subsistem real-time, jadi program akan menjadi portabel antara RTAI, QNX dan lainnya. Yang mengatakan, sebagian besar fungsi agak kecil dan langsung memanggil satu atau dua fungsi lainnya. Banyak yang bahkan static inline
berfungsi.
Jadi, pertama-tama, ini bukan aplikasi yang bisa saya profil. Tidak masuk akal untuk "mengidentifikasi leher botol" karena itu adalah perpustakaan, bukan aplikasi mandiri.
Kedua, ini seperti "Saya tahu ini tidak mungkin, saya mungkin juga mengatakannya kepada kompiler". Saya tidak secara aktif mencoba mengoptimalkan if
.
sumber
likely
danunlikely
ada dan apa yang mereka lakukan. Saya tidak menemukan apa pun yang benar-benar menyarankan kapan dan di mana cara terbaik untuk menggunakannya.Jawaban:
Apakah Anda memerlukan kinerja yang sangat buruk sehingga Anda bersedia mencemari kode Anda dengan itu? Ini optimasi kecil.
Kecuali Anda dapat menjawab
yes
semua hal di atas, jangan repot-repot dengan hal-hal seperti ini.Sunting: sebagai tanggapan terhadap sunting. Bahkan ketika Anda tidak dapat membuat profil, Anda biasanya dapat memperkirakan hotspot. Fungsi alokasi memori yang dipanggil oleh semua orang adalah kandidat yang baik, terutama karena hanya membutuhkan satu penggunaan makro untuk bekerja untuk seluruh perpustakaan.
sumber
(un)likely
makro jarang digunakan dan hanya dalam kode kritis kinerja sangat? Apakah "praktik buruk" sering menggunakannya, atau hanya "tidak perlu"?if (likely(x==2 || x==3)) doOneThing(); else switch(x) { ... }
, mungkin menilai bahwa penggunaan programerif
untuk nilai 2 dan 3 bukan hanya konsekuensi dari programmer yang tidak mengetahui bahwa C dapat mengaitkan duacase
label dengan handler tunggal.Jika Anda menulis untuk x86 / x64 (dan tidak menggunakan CPU berusia 20 tahun), keuntungan kinerja dari menggunakan __builtin_expect () akan diabaikan jika ada. Alasannya adalah bahwa CPU x86 / x64 modern (tidak 100% yakin tentang Atom), memiliki prediksi cabang dinamis, jadi pada dasarnya CPU "belajar" tentang cabang yang diambil lebih sering. Tentu, informasi ini dapat disimpan hanya untuk sejumlah cabang, namun, hanya ada dua kasus yang mungkin. Jika (a) itu cabang "sering digunakan", maka program Anda akan mendapat manfaat dari prediksi cabang dinamis itu, dan jika (b) itu cabang "langka", Anda tidak akan benar-benar melihat hit kinerja yang realistis karena salah duga di cabang langka seperti itu (20 siklus CPU misprediksi cabang tidak terlalu buruk jika terjadi sekali di bulan biru).
NB: ini TIDAK menyiratkan bahwa pada x86 / x64 modern pentingnya misprediksi cabang menjadi lebih rendah: cabang mana pun dengan peluang 50-50 melompat-nojump akan tetap dikenai penalti (siklus CPU IIRC 10-20), jadi dalam loop internal cabang mungkin masih perlu dihindari. Hanya pentingnya __builtin_expect () pada x86 / x64 yang telah berkurang (IIRC, sekitar 10-15 tahun yang lalu atau lebih) - sebagian besar karena prediksi cabang dinamis.
NB2: untuk platform lain di luar x86 / x64, YMMV.
sumber
unlikely
-notasi.