2011-08-19 2 views
4

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))

+0

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

+1

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

+0

@wberry: Vous avez raison, comme le suggère Jean-Paul en utilisant le réacteur 'epoll'. Vérifiez son lien. –

Répondre

1

Essayez de profiler l'application à différents niveaux de concurrence et voir quelles choses deviennent plus lentes lorsque vous ajoutez plus de connexions.

select est un candidat probable; Si vous constatez qu'il utilise de plus en plus de temps lorsque vous ajoutez des connexions, essayez using the poll or epoll reactor.

+0

Hé, désolé d'avoir pris tant de temps pour vous répondre, mais je n'ai pas eu accès au cours du week-end pour faire les tests. Je les ai maintenant lancés et j'ai posté quelques images (voir [link] (http://imgur.com/a/k9u8o)) Les choses que j'ai remarquées étaient les suivantes: –

+0

Le réacteur epoll semblait avoir moins de variation dans le débit. Alors que les appels aux fonctions doPoll et doSelect diminuent à mesure que le nombre de pairs augmente, cela ne semble pas être un bon indicateur. (pour doPoll le nombre d'appels a diminué de moitié, mais le débit a diminué de seulement 7%, et dans * un cas pour sélectionner les appels ont diminué mais le débit a augmenté.) La seule chose que j'ai trouvée qui corrige entre débit et appels était le main.py:49 (envoyer), mais ce n'est pas surprenant car c'est là que j'envoie les messages. * va ré-exécuter ce test sous peu à dbl vérifier –

Questions connexes