Je développe un programme permettant la simulation de réseaux sur une seule machine. Pour cela, j'utilise Twisted pour les E/S asynchrones, car avoir un thread pour chaque 'connexion' pourrait être un peu trop. (J'ai également mis en œuvre un programme similaire en Java en utilisant leur NIO). Cependant, comme je redimensionne la taille du réseau émulé le débit sur les baisses Twisted. En comparant cela à l'implémentation Java, pour la même taille de réseau, le débit Java continue de croître. (Le taux de croissance ralentit, mais c'est toujours une augmentation). E.g. (Python 100 nœuds = 58 Mo de débit total, 300 nœuds = 45 Mo, Java 100 nœuds = 24 Mo, 300 nœuds = 56 Mo).Diminution de la limite de débit torsadée
Je me demande si quelqu'un a des suggestions sur les raisons pour lesquelles cela pourrait se produire? La seule raison à laquelle je peux penser est que le Java a chaque 'peer' fonctionnant dans son propre thread (qui contient son propre sélecteur qui surveille les connexions des pairs). Dans la version python tout est enregistré avec le réacteur (et par la suite le seul sélecteur). Comme le python évolue, le sélecteur ne peut pas répondre aussi vite. Cependant, il ne s'agit que d'une supposition, si quelqu'un a des informations plus concrètes, il serait appriciated.
EDIT: J'ai effectué quelques tests comme suggéré par Jean-Paul Calderone, les résultats sont affichés au imgur. Pour ceux qui pourraient se demander le débit moyen suivant a été signalé pour les tests. (Le profilage a été fait avec cprofile, des tests ont été effectués pendant 60 secondes)
Epoll réacteur: 100 Pairs: 20.34 MB, 200 Pairs: 18.84 MB, 300 Pairs: 17,4 MB
Select réacteur: 100 Pairs : 18,86 Mo, 200 pairs: 19,08 Mo, 300 pairs: 16,732 Mo
Quelques choses qui semblaient monter et descendre avec le débit signalé étaient les appels faits à main.py:48(send), mais cette corrolation n'est pas vraiment une surprise car c'est là que les données sont envoyées. Pour les deux réacteurs, le temps passé dans la fonction d'envoi sur le (s) socket (s) augmentait lorsque le débit diminuait, et le nombre d'appels à la fonction d'envoi diminuait lorsque le débit diminuait. (C'est-à-dire: plus de temps a été passé à envoyer sur le socket, avec moins d'appels à envoyer sur une socket.) 2.5 sec pour epoll {méthode 'envoi' des objets '_socket.socket'} sur 100 pairs pour 413600 appels, à 5.5 sec pour epoll sur 300 pairs, pour 354300 appels.
Afin de tenter de répondre à la question initiale, est-ce que ces données semblent indiquer que le sélecteur est un facteur limitant? Le temps passé dans le Sélecteur semble diminuer au fur et à mesure que le nombre de pairs augmente (si le sélecteur ralentissait tout, ne s'attendrait-il pas à ce que le temps passé à l'intérieur augmente?) Y at-il autre chose qui pourrait ralentir la quantité de données envoyées? ? (L'envoi des données est juste une fonction pour chaque pair qui est enregistré avec reactor.calllater encore et encore.C'est le main.py:49 (send))
Si vous utilisez 'deferToThread' chaque fois que cela est possible (même pour les callbacks et les errback explicitement), vous risquez de rencontrer une limitation de Twisted ou même de CPython. Avez-vous essayé d'augmenter la taille du pool de threads Twisted, ou de courir sous PyPy ou Stackless Python? – wberry
Une autre chose qui pourrait avoir de l'importance dans le haut de gamme est le réacteur que vous utilisez.Par défaut, Twisted utilise 'SelectReactor' sous Unix. D'autres classes de réacteurs sont fournies. Je n'ai jamais utilisé aucun des autres. Ce n'est pas un cas d'utilisation courant d'utiliser un réacteur différent, mais il peut y en avoir un qui est conçu pour un filetage à degré élevé. – wberry
@wberry: Vous avez raison, comme le suggère Jean-Paul en utilisant le réacteur 'epoll'. Vérifiez son lien. –