Je ne m'attendrais pas à voir une énorme différence de performances entre le bord et le niveau déclenché.
Pour les déclenchements sur front, vous devez toujours vider le tampon d'entrée, vous avez donc un appel système recv inutile (renvoyant juste EWOULDBLOCK). Mais pour le niveau déclenché, vous pouvez utiliser plus d'appels système epoll_wait. Comme le souligne la page de manuel, éviter la famine peut être légèrement plus facile en mode déclenché par niveau.
La vraie différence est que lorsque vous souhaitez utiliser plusieurs threads, vous devrez utiliser le mode déclenché par les bords (bien que vous deviez toujours faire attention à la bonne synchronisation).
La différence n'est visible que lorsque vous utilisez des sessions de longue durée et que vous êtes obligé de vous arrêter/démarrer constamment à cause de tampons pleins/vides (généralement avec un proxy). Lorsque vous faites cela, vous avez le plus souvent besoin d'un cache d'événements, et lorsque votre cache d'événements traite des événements, vous pouvez utiliser ET et éviter toute danse epoll_ctl(DEL)+epoll_ctl(ADD). Pour les sessions de courte durée, les économies sont moins évidentes, car pour ET, vous aurez besoin d'au moins un appel epoll_ctl(ADD) pour activer l'interrogation sur le FD, et si vous ne vous attendez pas à en avoir plus pendant la durée de la session (par exemple :les échanges sont plus petits que les tampons la plupart du temps), alors vous ne devriez pas vous attendre à une différence. La plupart de vos économies proviendront généralement de l'utilisation d'un cache d'événements uniquement, car vous pouvez souvent effectuer de nombreuses opérations (par exemple :des écritures) sans interrogation grâce aux tampons du noyau.
Lorsqu'il est utilisé comme interface déclenchée par le bord, pour des raisons de performances, il est possible d'ajouter le descripteur de fichier à l'intérieur de l'interface epoll (EPOLL_CTL_ADD) une fois en spécifiant (EPOLLIN|EPOLLOUT). Cela vous permet d'éviter de basculer continuellement entre EPOLLIN et EPOLLOUT en appelant epoll_ctl(2) avec EPOLL_CTL_MOD.
Q9 Dois-je lire/écrire en continu un descripteur de fichier jusqu'à EAGAINlorsque j'utilise l'indicateur EPOLLET (comportement déclenché par le bord) ?
A9 Receiving an event from epoll_wait(2) should suggest to you that
such file descriptor is ready for the requested I/O operation. You
must consider it ready until the next (nonblocking) read/write
yields EAGAIN. When and how you will use the file descriptor is
entirely up to you.
For packet/token-oriented files (e.g., datagram socket, terminal in
canonical mode), the only way to detect the end of the read/write
I/O space is to continue to read/write until EAGAIN.
For stream-oriented files (e.g., pipe, FIFO, stream socket), the
condition that the read/write I/O space is exhausted can also be
detected by checking the amount of data read from / written to the
target file descriptor. For example, if you call read(2) by asking
to read a certain amount of data and read(2) returns a lower number
of bytes, you can be sure of having exhausted the read I/O space
for the file descriptor. The same is true when writing using
write(2). (Avoid this latter technique if you cannot guarantee
that the monitored file descriptor always refers to a stream-ori‐
ented file.)