Apa kelebihan / kekurangan menggunakan fungsi inline di C ++? Saya melihat bahwa itu hanya meningkatkan kinerja untuk kode yang dihasilkan oleh kompiler, tetapi dengan kompiler yang dioptimalkan saat ini, CPU cepat, memori besar dll. (Tidak seperti pada tahun 1980 <di mana memori langka dan semuanya harus masuk dalam memori 100KB) apa keuntungan yang mereka miliki saat ini?
c++
inline-functions
Lennie De Villiers
sumber
sumber
inline
adalah kata kunci c ++ dan inlining adalah teknik optimisasi kompiler. Lihat pertanyaan ini " kapan saya harus menulis kata kunciinline
untuk fungsi / metode " untuk jawaban yang benar.Jawaban:
Fungsi sebaris lebih cepat karena Anda tidak perlu mendorong dan memunculkan / mematikan tumpukan seperti parameter dan alamat pengirim; Namun, itu membuat biner Anda sedikit lebih besar.
Apakah itu membuat perbedaan yang signifikan? Tidak cukup terasa pada perangkat keras modern bagi kebanyakan orang. Tapi itu bisa membuat perbedaan, yang cukup bagi sebagian orang.
Menandai sesuatu yang sebaris tidak memberi Anda jaminan bahwa itu akan sejajar. Itu hanya saran untuk kompiler. Kadang-kadang itu tidak mungkin seperti ketika Anda memiliki fungsi virtual, atau ketika ada rekursi yang terlibat. Dan terkadang kompiler hanya memilih untuk tidak menggunakannya.
Saya bisa melihat situasi seperti ini membuat perbedaan yang dapat dideteksi:
sumber
Keuntungan
Kekurangan
Sihir Inlining
return 42 ;
pernyataan. Ini bagi saya inlining ekstrim . Ini jarang terjadi dalam kehidupan nyata, itu membuat waktu kompilasi lebih lama, tidak akan mengasapi kode Anda, dan akan membuat kode Anda lebih cepat. Tapi seperti grail, jangan mencoba menerapkannya di mana-mana karena kebanyakan pemrosesan tidak dapat diselesaikan dengan cara ini ... Tetap saja, ini keren kok ...:-p
sumber
3.2/6: There can be more than one definition of [..] inline function with external linkage [..] non-static function template
. Di 5.1.5 / 6For a generic lambda, the closure type has a public inline function call operator member template
. Dan di7.1.2/2: the use of inline keyword is to declare an inline function
mana itu adalah saran untuk menyelaraskan fungsi tubuh di titik panggilan. Jadi, saya menyimpulkan bahwa meskipun mereka dapat berperilaku sama, fungsi inline dan templat fungsi masih terpisah, gagasan ortogonal yang dapat dicampur (yaitu templat fungsi inline)Dalam bahasa C dan C ++ kuno,
inline
sepertiregister
: sebuah saran (tidak lebih dari sebuah saran) kepada kompiler tentang kemungkinan optimasi.Dalam C ++ modern,
inline
memberi tahu linker bahwa, jika banyak definisi (bukan deklarasi) ditemukan dalam unit terjemahan yang berbeda, semuanya sama, dan linker dapat dengan bebas menyimpan satu dan membuang semua yang lain.inline
wajib jika suatu fungsi (tidak peduli seberapa kompleks atau "linier") didefinisikan dalam file header, untuk memungkinkan banyak sumber untuk memasukkannya tanpa mendapatkan kesalahan "beberapa definisi" oleh linker.Fungsi anggota yang didefinisikan di dalam kelas adalah "inline" secara default, seperti fungsi templat (berbeda dengan fungsi global).
Perhatikan penyertaan fileA.h ke dalam dua file .cpp, menghasilkan dua contoh
afunc()
. Tautan akan membuang salah satunya. Jika tidakinline
ditentukan, penghubung akan mengeluh.sumber
Inlining adalah sebuah saran untuk kompiler yang bebas untuk diabaikan. Ini ideal untuk bit kode kecil.
Jika fungsi Anda sebaris, itu pada dasarnya dimasukkan dalam kode tempat pemanggilan fungsi dilakukan, alih-alih benar-benar memanggil fungsi yang terpisah. Ini dapat membantu dengan kecepatan karena Anda tidak harus melakukan panggilan yang sebenarnya.
Ini juga membantu CPU dalam pipelining karena mereka tidak perlu memuat ulang pipa dengan instruksi baru yang disebabkan oleh panggilan.
Satu-satunya kelemahan adalah kemungkinan peningkatan ukuran biner tetapi, selama fungsinya kecil, ini tidak terlalu menjadi masalah.
Saya cenderung menyerahkan keputusan-keputusan semacam ini kepada para penyusun saat ini (yah, yang pintar pula). Orang-orang yang menulisnya cenderung memiliki pengetahuan yang jauh lebih rinci tentang arsitektur yang mendasarinya.
sumber
Fungsi sebaris adalah teknik optimisasi yang digunakan oleh kompiler. Satu hanya dapat menambahkan kata kunci inline ke prototipe fungsi untuk membuat fungsi inline. Fungsi inline menginstruksikan kompiler untuk memasukkan seluruh tubuh fungsi di mana pun fungsi itu digunakan dalam kode.
Keuntungan :-
Tidak memerlukan fungsi panggilan overhead.
Ini juga menghemat overhead variabel push / pop pada stack, sambil memanggil fungsi.
Ini juga menghemat overhead panggilan balik dari suatu fungsi.
Ini meningkatkan lokalitas referensi dengan menggunakan cache instruksi.
Setelah in-lining, kompiler juga dapat menerapkan optimasi intra-prosedural jika ditentukan. Ini adalah yang paling penting, dengan cara ini kompiler sekarang dapat fokus pada penghapusan kode mati, dapat memberikan lebih banyak tekanan pada prediksi cabang, penghapusan variabel induksi dll.
Untuk mengetahui lebih lanjut tentang hal ini, seseorang dapat mengikuti tautan ini http://tajendrasengar.blogspot.com/2010/03/what-is-inline-function-in-cc.html
sumber
Saya ingin menambahkan bahwa fungsi sebaris sangat penting ketika Anda sedang membangun perpustakaan bersama. Tanpa menandai fungsi inline, itu akan diekspor ke perpustakaan dalam bentuk biner. Ini juga akan hadir dalam tabel simbol, jika diekspor. Di sisi lain, fungsi sebaris tidak diekspor, baik ke biner perpustakaan maupun ke tabel simbol.
Mungkin kritis ketika perpustakaan dimaksudkan untuk dimuat saat runtime. Mungkin juga mengenai perpustakaan yang sadar biner-kompatibel. Dalam kasus seperti itu jangan gunakan inline.
sumber
inline
ketika membangun perpustakaan bersama!Selama optimisasi, banyak kompiler akan inline fungsi bahkan jika Anda tidak menandainya. Anda biasanya hanya perlu menandai fungsi sebagai inline jika Anda tahu sesuatu yang tidak dikompilasi oleh kompiler, karena biasanya dapat membuat keputusan yang benar sendiri.
sumber
inline
memungkinkan Anda untuk menempatkan definisi fungsi di file header dan#include
file header itu di beberapa file sumber tanpa melanggar aturan satu definisi.sumber
Secara umum, akhir-akhir ini dengan kompiler modern apa pun yang mengkhawatirkan inlining sesuatu cukup banyak membuang waktu. Kompiler harus benar-benar mengoptimalkan semua pertimbangan ini untuk Anda melalui analisis kode sendiri dan spesifikasi bendera pengoptimalan yang diteruskan ke kompiler. Jika Anda peduli tentang kecepatan, beri tahu kompiler untuk mengoptimalkan kecepatan. Jika Anda peduli ruang, beri tahu kompiler untuk mengoptimalkan ruang. Sebagai jawaban lain disinggung, kompiler yang layak bahkan akan otomatis inline jika itu benar-benar masuk akal.
Juga, seperti yang telah dinyatakan orang lain, menggunakan inline tidak menjamin inline apa pun. Jika Anda ingin menjaminnya, Anda harus mendefinisikan makro alih-alih fungsi sebaris untuk melakukannya.
Kapan harus inline dan / atau mendefinisikan makro untuk memaksa inklusi? - Hanya ketika Anda memiliki peningkatan yang terbukti dan perlu terbukti dalam kecepatan untuk bagian penting dari kode yang diketahui memiliki pengaruh pada kinerja keseluruhan aplikasi.
sumber
Ini bukan soal kinerja. Baik C ++ dan C digunakan untuk pemrograman tertanam, duduk di atas perangkat keras. Jika Anda akan, misalnya, menulis interrupt handler, Anda perlu memastikan bahwa kode dapat dieksekusi sekaligus, tanpa register tambahan dan / atau halaman memori sedang ditukar. Saat itulah inline berguna. Compiler yang baik melakukan beberapa "inlining" sendiri ketika kecepatan diperlukan, tetapi "inline" memaksa mereka.
sumber
Jatuh ke masalah yang sama dengan menguraikan fungsi ke dalam begitu banyak perpustakaan. Tampaknya fungsi yang digariskan tidak dikompilasi ke perpustakaan. sebagai akibatnya linker mengeluarkan kesalahan "referensi tidak terdefinisi", jika executable ingin menggunakan fungsi inline dari library. (Kebetulan saya mengkompilasi sumber Qt dengan gcc 4.5.
sumber
Mengapa tidak membuat semua fungsi sebaris secara default? Karena ini merupakan trade off teknik. Setidaknya ada dua jenis "optimasi": mempercepat program dan mengurangi ukuran (jejak memori) program. Inlining umumnya mempercepat. Itu menghilangkan fungsi panggilan overhead, menghindari mendorong lalu menarik parameter dari stack. Namun, ini juga membuat tapak memori program lebih besar, karena setiap pemanggilan fungsi sekarang harus diganti dengan kode lengkap fungsi. Untuk membuat segalanya semakin rumit, ingat bahwa CPU menyimpan potongan memori yang sering digunakan dalam cache pada CPU untuk akses ultra cepat. Jika Anda membuat gambar memori program cukup besar, program Anda tidak akan dapat menggunakan cache secara efisien, dan dalam kasus terburuk inlining sebenarnya dapat memperlambat program Anda.
sumber
Profesor ilmu komputer kami mendesak kami untuk tidak pernah menggunakan inline dalam program c ++. Ketika ditanya mengapa, ia dengan ramah menjelaskan kepada kami bahwa kompiler modern harus mendeteksi kapan harus menggunakan inline secara otomatis.
Jadi ya, inline dapat menjadi teknik optimisasi untuk digunakan sedapat mungkin, tetapi tampaknya ini adalah sesuatu yang sudah dilakukan untuk Anda kapan pun dimungkinkan untuk inline suatu fungsi.
sumber
inline
di C ++ memiliki dua arti yang sangat berbeda - hanya satu yang terkait dengan optimasi, dan profesor Anda benar mengenai hal itu. Namun, makna keduainline
sering diperlukan untuk memenuhi Aturan Satu Definisi .Kesimpulan dari diskusi lain di sini:
Apakah ada kekurangan dengan fungsi sebaris?
Ternyata, tidak ada yang salah dengan menggunakan fungsi inline.
Tetapi perlu diperhatikan hal-hal berikut!
Terlalu sering menggunakan inlining sebenarnya bisa membuat program lebih lambat. Bergantung pada ukuran fungsi, dengan menggariskannya dapat menyebabkan ukuran kode bertambah atau berkurang. Inlining fungsi pengakses yang sangat kecil biasanya akan mengurangi ukuran kode sementara inlining fungsi yang sangat besar dapat secara dramatis meningkatkan ukuran kode. Pada prosesor modern, kode yang lebih kecil biasanya berjalan lebih cepat karena penggunaan cache instruksi yang lebih baik. - Panduan Google
Manfaat kecepatan fungsi inline cenderung berkurang ketika fungsi tumbuh dalam ukuran. Di beberapa titik, overhead panggilan fungsi menjadi kecil dibandingkan dengan pelaksanaan fungsi tubuh, dan manfaatnya hilang - Sumber
Ada beberapa situasi di mana fungsi sebaris mungkin tidak berfungsi:
Kata
__inline
kunci menyebabkan fungsi menjadi inline hanya jika Anda menentukan opsi optimisasi. Jika optimisasi ditentukan, apakah__inline
dihormati atau tidak tergantung pada pengaturan opsi pengoptimal sebaris. Secara default, opsi inline berlaku setiap kali optimizer dijalankan. Jika Anda menentukan pengoptimalan, Anda juga harus menentukan opsi noinline jika Anda ingin__inline
kata kunci diabaikan. -Sumbersumber
inline
kata kunci untuk menentukan apakah kode inline atau tidak semua poin yang dibuat di atas salah. Mereka akan benar jika kompiler menggunakan kata kunci untuk inlining (itu hanya digunakan untuk menentukan menandai beberapa definisi untuk tujuan menghubungkan).