10
votes

Performance Epoll

Quelqu'un peut-il m'aider s'il vous plaît à répondre aux questions sur Epoll_Wait.

  1. est-il surchargé d'utiliser de nombreux threads qui appellent Epoll_Wait sur le même FDS défini pour servir à environ 100 000 sockets actives? ou cela suffira-t-il simplement à créer seulement 1 fil pour effectuer Epoll_Wait?

  2. Combien de threads se réveilleront d'Epoll_Wait lorsque, par exemple, un seul socket est prêt à lire des données? Je veux dire, peut-il y avoir une situation lorsque 2 threads ou plus se réveillent d'Epoll_wait, mais auront les mêmes FDS dans les événements résultants?

  3. Quel est le meilleur moyen d'organiser des threads sur le serveur qui fonctionne avec de nombreux clients actifs (par exemple 50k +). La meilleure façon dont je pense est la suivante: Thread Travailleur d'E / S qui perfroms Epoll_wait et E / S Opérations. + de nombreux threads de traitement de données qui traiteront les données reçues à partir de thread de travailleur d'E / S (peut prendre beaucoup de temps, telles que n'importe quelle logique de jeu) et composer de nouvelles données pour le fil de travail d'E / S pour envoyer à client. Ai-je raison dans cette approche, ou quelqu'un peut-il m'aider à trouver le meilleur moyen d'organiser cela?

    Merci d'avance, Valentin


0 commentaires

3 Réponses :


5
votes

Je vous recommande cette lecture à partir de 2006: http://www.kegel.com/c10k.html < / a>


0 commentaires

12
votes
  1. Lorsque vous utilisez Epoll, vous souhaitez former votre fil de fil au nombre de cœurs physiques CPU (ou d'une unité d'expédition HyperTythreille) que vous souhaitez utiliser pour le traitement. L'utilisation d'un seul thread pour le travail signifie qu'au plus d'un noyau sera actif à la fois.

  2. Cela dépend du mode du descripteur de fichier EPOLL. Les événements peuvent être "tranchants", ce qui signifie qu'elles ne se produisent qu'une fois atomiquement ou "de niveau déclenché" signifiant que tout appelant reçoit un événement s'il y a de l'espace dans la mémoire tampon.

  3. Pas assez d'informations pour dire. Je suggérerais de ne pas avoir de threads à usage spécial du tout, de la simplicité et de manipuler simplement la "commande" de chaque événement dans le fil dans lequel elle est reçue. Mais évidemment, cela dépend de la nature de votre application.


6 commentaires

Donc, si j'ai bien compris le meilleur schéma à la prochaine apparence: Créez le nombre de threads d'E / S égaux au nombre de cœurs dans le système et utilisez et Epoll_Wait. Chaque fil aura son propre sous-ensemble de FD. Par exemple 4 threads pour processeur IC2Q. Chaque thread gère des connexions de 25 km et au total 100k. Et la question suivante: Dois-je avoir un fil séparé qui va epoll_wait Sactoir et gérera dans quel sous-ensemble de la prise nouvellement acceptée d'ID sera ajoutée? Et est-ce que c'est thread-coffre-fort d'ajouter une FD nouvellement acceptée à l'aide d'Epoll_Ctl dans un fil, tandis que d'autres font de l'époll_wait sur ce sous-ensemble?


J'attendrais sur tous les descripteurs de tous les discussions, en fait. À moins que vous sachiez que vous pouvez gagner des effets de cache en isolant les travaux connexes sur des processeurs spécifiques, c'est généralement une perte de faire ce type de partitionnement. Vous finissez par affamer une CPU tandis qu'un autre ait toujours du travail qui pourrait être fait. Et oui: les opérations d'Epoll sont atomiques (bien que évidemment, vous devrez verrouiller l'une de vos propres réprimez vous-même).


Comment se comportera et epoll_wait? Tous les fils se réveillent-ils de Epoll_wait? Ou juste seulement 1 fil? Si j'ai bien compris et epoll_wait est atomique et ne se produira qu'une fois pour les FD prêts. Par exemple: j'ai 2 FD et 2 threads en attente sur Epoll_Wait. 1 FD devient prêt et seulement 1 thread sera repris et si d'autres FD deviendront prêts lors du 1er offres de threads avec la première FD, le deuxième thread sera repris. Andy, est-ce correct?


@Valentin (il est très tard, mais) oui, je crois que c'est correct.


@Valentin Utilisez Epolloneshot si vous souhaitez vous garantir la réveil qu'une fois par descripteur de fichier. EPOLLET Kinda atteint la même chose, mais sans une garantie aussi forte. Ce explique plus en détail.


Cette réponse est évidente. Voir ma réponse pour plus de détails.



-3
votes

En réalité, il s'agit d'une mauvaise utilisation de l'époll.

Vous ne devez absolument pas partager la FD Epoll entre les threads. Sinon, vous avez la possibilité qu'un seul fil a une partie des données entrantes sur une FD et un autre thread sur le même FD sans aucun moyen de savoir quelle partie des données était avant l'autre.

Appelez simplement Epoll_Create dans chaque fil qui appelle Epoll_Wait. Sinon, les E / S sont cassés.


1 commentaires

Il me semble que vous êtes confondre la FD Epoll avec la FD de la prise réelle. L'utilisation d'Epoll à travers plusieurs threads est absolument possible, en fait, c'est l'un des points de l'utilisation. Pour ne pas avoir une condition de course entre les threads, vous devez soit utiliser epolloneshot ou, dans les noyaux plus récents, epollexclusive . Cet excellent blog explique les détails.