Apa antara panggilan yang mungkin dan tidak mungkin di Kernel. Saat mencari melalui sumber kernel saya menemukan pernyataan ini.
# define likely(x) __builtin_expect(!!(x), 1)
# define unlikely(x) __builtin_expect(!!(x), 0)
Bisakah seseorang menjelaskannya?
Jawaban:
Mereka adalah petunjuk kompiler untuk GCC. Mereka digunakan dalam kondisi untuk memberi tahu kompiler jika cabang kemungkinan diambil atau tidak. Ini dapat membantu kompiler meletakkan kode sedemikian rupa sehingga optimal untuk hasil yang paling sering.
Mereka digunakan seperti ini:
Ini harus digunakan dengan sangat hati-hati (yaitu berdasarkan hasil profil cabang yang sebenarnya). Petunjuk yang salah dapat menurunkan kinerja (jelas).
Beberapa contoh bagaimana kode dapat dioptimalkan mudah ditemukan dengan mencari
GCC __builtin_expect
. Blog ini memposting optimasi gcc: __builtin_expect misalnya rincian pembongkaran dengannya.Jenis optimasi yang dapat dilakukan sangat spesifik untuk prosesor. Gagasan umum adalah bahwa seringkali, prosesor akan menjalankan kode lebih cepat jika tidak bercabang / melompati semua tempat. Semakin linear, dan semakin mudah diprediksi cabang, semakin cepat akan berjalan. (Ini terutama berlaku untuk prosesor dengan pipa dalam misalnya).
Jadi kompiler akan memancarkan kode sedemikian rupa sehingga cabang yang paling mungkin tidak akan melibatkan lompatan jika itu yang lebih disukai CPU target, misalnya.
sumber
Mari kita dekompilasi untuk melihat apa yang dilakukan GCC 4.8 dengan itu
Tanpa harapan
Kompilasi dan dekompilasi dengan GCC 4.8.2 x86_64 Linux:
Keluaran:
Urutan instruksi dalam memori tidak berubah: pertama
printf
dan kemudianputs
danretq
kembali.Dengan harapan
Sekarang ganti
if (i)
dengan:dan kami mendapatkan:
The
printf
(dikompilasi untuk__printf_chk
) dipindahkan ke akhir fungsi, setelahputs
dan kembali untuk meningkatkan prediksi cabang seperti yang disebutkan oleh jawaban lainnya.Jadi pada dasarnya sama dengan:
Optimasi ini tidak dilakukan dengan
-O0
.Tapi semoga berhasil menulis contoh yang berjalan lebih cepat dengan
__builtin_expect
tanpa, CPU benar-benar pintar saat itu . Upaya naif saya ada di sini .C ++ 20
[[likely]]
dan[[unlikely]]
C ++ 20 telah menstandarkan C ++ built-in tersebut: /programming/51797959/how-to-use-c20s- maybe-unihood-attribute-in-if-else-statement Mereka kemungkinan akan (a pun!) lakukan hal yang sama.
sumber