Untuk jumlah soket yang sangat kecil (bervariasi tergantung pada perangkat keras Anda, tentu saja, tetapi kita berbicara tentang sesuatu di urutan 10 atau kurang), pilih dapat mengalahkan epoll dalam penggunaan memori dan kecepatan runtime. Tentu saja, untuk sejumlah kecil soket, kedua mekanisme tersebut sangat cepat sehingga Anda tidak terlalu peduli dengan perbedaan ini di sebagian besar kasus.
Namun satu klarifikasi. Baik pilih dan skala epoll secara linier. Namun, perbedaan besar adalah bahwa API yang menghadap ke ruang pengguna memiliki kerumitan yang didasarkan pada hal-hal yang berbeda. Biaya select
panggilan kira-kira sama dengan nilai deskriptor file bernomor tertinggi yang Anda berikan. Jika Anda memilih pada satu fd, 100, maka itu kira-kira dua kali lebih mahal daripada memilih pada satu fd, 50. Menambahkan lebih banyak fds di bawah yang tertinggi tidaklah cukup gratis, jadi ini sedikit lebih rumit daripada ini dalam praktiknya, tapi ini adalah perkiraan pertama yang baik untuk sebagian besar implementasi.
Biaya epoll lebih mendekati jumlah deskriptor file yang benar-benar memiliki acara di dalamnya. Jika Anda memantau 200 deskriptor file, tetapi hanya 100 yang memiliki peristiwa di dalamnya, Anda (sangat kasar) hanya membayar untuk 100 deskriptor file aktif tersebut. Di sinilah epoll cenderung menawarkan salah satu keunggulan utamanya dibandingkan pilihan. Jika Anda memiliki seribu klien yang sebagian besar menganggur, maka ketika Anda menggunakan pilih Anda masih membayar untuk seribu klien tersebut. Namun, dengan epoll, sepertinya Anda hanya punya sedikit - Anda hanya membayar yang aktif pada waktu tertentu.
Semua ini berarti epoll akan mengurangi penggunaan CPU untuk sebagian besar beban kerja. Sejauh penggunaan memori berjalan, itu sedikit dilempar. select
berhasil merepresentasikan semua informasi yang diperlukan dengan cara yang sangat kompak (satu bit per deskriptor file). Dan batasan FD_SETSIZE (biasanya 1024) tentang berapa banyak deskriptor file yang dapat Anda gunakan select
berarti Anda tidak akan pernah menghabiskan lebih dari 128 byte untuk masing-masing dari tiga set fd yang dapat Anda gunakan denganselect
(baca, tulis, pengecualian). Dibandingkan dengan maksimal 384 byte itu, epoll adalah semacam babi. Setiap deskriptor file diwakili oleh struktur multi-byte. Namun, secara absolut, itu tetap tidak akan menggunakan banyak memori. Anda dapat mewakili sejumlah besar deskriptor file dalam beberapa lusin kilobyte (kira-kira 20k per 1000 file deskriptor, menurut saya). Dan Anda juga dapat membuang fakta bahwa Anda harus menghabiskan semua 384 byte tersebut dengan select
jika Anda hanya ingin memantau satu deskriptor file tetapi nilainya kebetulan 1024, sedangkan dengan epoll Anda hanya menghabiskan 20 byte. Tetap saja, semua angka ini cukup kecil, jadi tidak ada bedanya.
Dan ada juga manfaat lain dari epoll, yang mungkin sudah Anda ketahui, tidak terbatas pada deskriptor file FD_SETSIZE. Anda dapat menggunakannya untuk memantau deskriptor file sebanyak yang Anda miliki. Dan jika Anda hanya memiliki satu deskriptor file, tetapi nilainya lebih besar dari FD_SETSIZE, epoll juga berfungsi dengan itu, tetapi select
tidak.
Secara acak, saya juga baru-baru ini menemukan satu kelemahan kecil epoll
dibandingkan dengan select
atau poll
. Meskipun tidak satu pun dari ketiga API ini mendukung file normal (yaitu, file pada sistem file), select
dan poll
kurangnya dukungan ini seperti melaporkan deskriptor seperti yang selalu dapat dibaca dan selalu dapat ditulisi. Hal ini membuat mereka tidak cocok untuk semua jenis I / O sistem file non-pemblokiran yang berarti, program yang menggunakan select
atau poll
dan kebetulan menemukan deskriptor file dari sistem file setidaknya akan terus beroperasi (atau jika gagal, itu tidak akan terjadi karena dari select
atau poll
), meskipun itu mungkin tidak dengan performa terbaik.
Di sisi lain, epoll
akan gagal dengan cepat dengan kesalahan ( EPERM
, tampaknya) ketika diminta untuk memantau deskriptor file tersebut. Sebenarnya, ini hampir tidak salah. Ini hanya menandakan kurangnya dukungan secara eksplisit. Biasanya saya akan memuji kondisi kegagalan eksplisit, tetapi yang ini tidak berdokumen (sejauh yang saya tahu) dan menghasilkan aplikasi yang benar-benar rusak, daripada yang hanya beroperasi dengan kinerja yang berpotensi terdegradasi.
Dalam praktiknya, satu-satunya tempat yang pernah saya lihat ini muncul adalah saat berinteraksi dengan stdio. Seorang pengguna mungkin mengarahkan stdin atau stdout dari / ke file normal. Padahal sebelumnya stdin dan stdout akan menjadi pipa - didukung oleh epoll saja - itu kemudian menjadi file normal dan epoll gagal dengan keras, melanggar aplikasi.
poll
kelengkapan?