Domanda

Tutto ciò che ho letto e sperimentato (app basate su Tornado) mi porta a credere che ePoll sia un sostituto naturale per le reti basate su Select e Poll, in particolare con Twisted.Il che mi rende paranoico, è piuttosto raro che una tecnica o metodologia migliore non abbia un prezzo.

Leggendo un paio di dozzine di confronti tra epoll e alternative mostra che epoll è chiaramente il campione di velocità e scalabilità, in particolare che si adatta in modo lineare, il che è fantastico.Detto questo, per quanto riguarda l'utilizzo del processore e della memoria, epoll è ancora il campione?

È stato utile?

Soluzione

Per un numero molto piccolo di socket (varia a seconda dell'hardware, ovviamente, ma stiamo parlando di qualcosa nell'ordine di 10 o meno), select può battere epoll nell'utilizzo della memoria e nella velocità di runtime.Naturalmente, per un numero così piccolo di socket, entrambi i meccanismi sono così veloci che nella stragrande maggioranza dei casi non ti interessa davvero questa differenza.

Una precisazione, però.Sia select che epoll si ridimensionano linearmente.Una grande differenza, tuttavia, è che le API rivolte allo spazio utente presentano complessità basate su cose diverse.Il costo di a select call va all'incirca con il valore del descrittore di file con il numero più alto che gli passi.Se selezioni su un singolo fd, 100, allora è circa il doppio più costoso che selezionare su un singolo fd, 50.Aggiungere più fd al di sotto del massimo non è del tutto gratuito, quindi in pratica è un po' più complicato di così, ma questa è una buona prima approssimazione per la maggior parte delle implementazioni.

Il costo di epoll è più vicino al numero di descrittori di file che effettivamente contengono eventi.Se stai monitorando 200 descrittori di file, ma solo 100 di essi contengono eventi, allora stai (in modo molto approssimativo) pagando solo per quei 100 descrittori di file attivi.È qui che epoll tende ad offrire uno dei suoi maggiori vantaggi rispetto a select.Se hai mille clienti che sono per lo più inattivi, quando usi select stai comunque pagando per tutti e mille.Tuttavia, con epoll, è come se ne avessi solo pochi: paghi solo per quelli attivi in ​​un dato momento.

Tutto ciò significa che epoll comporterà un minore utilizzo della CPU per la maggior parte dei carichi di lavoro.Per quanto riguarda l'utilizzo della memoria, è un po' complicato. select riesce a rappresentare tutte le informazioni necessarie in modo estremamente compatto (un bit per descrittore di file).E la limitazione FD_SETSIZE (tipicamente 1024) sul numero di descrittori di file che puoi utilizzare con select significa che non spenderai mai più di 128 byte per ciascuno dei tre set fd con cui puoi utilizzare select (lettura, scrittura, eccezione).Rispetto a quei 384 byte massimi, epoll è una specie di maiale.Ogni descrittore di file è rappresentato da una struttura multibyte.Tuttavia, in termini assoluti, non utilizzerà ancora molta memoria.Puoi rappresentare un numero enorme di descrittori di file in poche decine di kilobyte (circa 20k per 1000 descrittori di file, credo).E puoi anche aggiungere il fatto che devi spendere tutti i 384 byte select se vuoi monitorare solo un descrittore di file ma il suo valore sembra essere 1024, mentre con epoll spenderesti solo 20 byte.Tuttavia, tutti questi numeri sono piuttosto piccoli, quindi non fa molta differenza.

E c'è anche quell'altro vantaggio di epoll, di cui forse sei già a conoscenza, che non è limitato ai descrittori di file FD_SETSIZE.Puoi usarlo per monitorare tutti i descrittori di file che hai.E se hai solo un descrittore di file, ma il suo valore è maggiore di FD_SETSIZE, epoll funziona anche con quello, ma select non.

Casualmente, recentemente ho anche scoperto un leggero inconveniente epoll paragonato a select O poll.Anche se nessuna di queste tre API supporta file normali (ovvero file su un file system), select E poll presentare questa mancanza di supporto riportando tali descrittori come sempre leggibili e sempre scrivibili.Ciò li rende inadatti a qualsiasi tipo significativo di I/O del filesystem non bloccante, un programma che utilizza select O poll e capita di incontrare un descrittore di file dal filesystem almeno continuerà a funzionare (o se fallisce, non sarà a causa di select O poll), anche se forse non con le migliori prestazioni.

D'altra parte, epoll fallirà velocemente con un errore (EPERM, a quanto pare) quando viene chiesto di monitorare tale descrittore di file.A rigor di termini, questo non è affatto sbagliato.Sta semplicemente segnalando la sua mancanza di sostegno in modo esplicito.Normalmente applaudirei condizioni di errore esplicite, ma questa non è documentata (per quanto ne so) e si traduce in un'applicazione completamente danneggiata, piuttosto che in una che funziona semplicemente con prestazioni potenzialmente degradate.

In pratica, l'unico posto in cui ho visto questo verificarsi è stato durante l'interazione con stdio.Un utente potrebbe reindirizzare stdin o stdout da/verso un file normale.Mentre in precedenza stdin e stdout sarebbero stati una pipe - supportata perfettamente da epoll - diventa un file normale ed epoll fallisce rumorosamente, interrompendo l'applicazione.

Altri suggerimenti

Nei test alla mia azienda, un problema con l'epoll () è venuto, così un unico costo rispetto per selezionare.

Quando si tenta di leggere dalla rete con un timeout, creando un epoll_fd (anziché un FD_SET), e aggiungendo il fd al epoll_fd, è molto più costoso di creare un FD_SET (che è un semplice malloc).

Come per la precedente risposta, come il numero di DF nel processo diventa grande, il costo di select () diventa più alta, ma nel nostro test, anche con valori FD in 10.000 di selezionare era ancora un vincitore. Questi sono casi in cui v'è un solo fd che un thread è in attesa, e semplicemente cercando di superare il fatto che la rete lettura, scrittura e di rete, non timeout quando si utilizza un modello di thread di blocco. Naturalmente, i modelli filetto di bloccaggio sono basso rendimento rispetto ai non bloccanti sistemi di reattori, ma ci sono occasioni in cui, da integrare con un particolare codice di base legacy, è richiesta.

Questo tipo di caso d'uso è raro in applicazioni ad alte prestazioni, perché un modello di reattore non ha bisogno di creare un nuovo epoll_fd ogni volta. Per il modello in cui un epoll_fd è longevo --- che è chiaramente preferibile per qualsiasi progetto di server ad alte prestazioni --- epoll è il chiaro vincitore in ogni modo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top