none
Socket : Mauvaise performance en émission pour des données de 6Mo en localhost RRS feed

  • Discussion générale

  • Je travaille sur une application composé de 2 processus qui communique par socket

    Ces 2 processus sont exécutés sur le même serveur.

    Le processus "Serveur" transmet au client toutes les 30ms, des blocs de données d'environ 6Mo.

    J'ai installé l'application sur 2 serveurs différents et j'ai observés des différences de performances.

    Sur le Server A ( Xeon 5620, Windows Server 2008 R2), chaque appel à la fonction send dure environ 4ms.

    Sur le Server B ( Bi Xeon E5-2620, Windows Server 2008 R2), le 1er appel à la fonction send dure 11ms puis le second appel dure 70ms, et ainsi de suite. Ici un appel sur 2 dure ~70ms.

    Je ne comprends pas les performances de la fonction send sur le Server B.

    Sur les 2 serveurs, les buffers des sockets SND_BUF & RCV_BUF sont dimensions à 8Ko (Paramètres par défaut).

    Est-ce qu'il y a des paramètres systèmes sur les sockets qui pourraient avoir un impact sur les performances ?

    Merci

    • Type modifié Aurel Bera mercredi 11 juin 2014 12:41 disc
    jeudi 5 juin 2014 09:35

Toutes les réponses

  • Oui, plein, comme l'utilisation de l'algorithme de Nagle ou pas etc... .

    Pouvez-vous utiliser un sniffer réseau pour voir ce trafic et bien vérifier que la différence est bien lié au réseau et non à des différences dans le schedulling des processus ?


    Paul Bacelar, Ex - MVP VC++

    jeudi 5 juin 2014 13:01
    Modérateur
  • N'étant pas un spécialiste des réseaux, quels types d'informations dois-je controler avec le sniffer réseau ?

    Est-ce que le logiciel Wireshark est l'outil approprié pour faire ce test de trafic ?

    vendredi 6 juin 2014 07:44
  • J'ai utilisé Wireshark et fait un filtre sur les packets IP ayant l'adresse IP de destination 127.0.0.1.

    Wireshark ne capture rien.

    Dans mon application, j'utilise les sockets pour faire une communication IPC (entre 2 processus) en utilisant le protocole TPC/IP.

    Attention les 2 processus sont exécutés sur la même machine (adresses IP utilisé 127.0.0.1).

    • Modifié Gawik vendredi 6 juin 2014 10:41
    vendredi 6 juin 2014 08:10
  • Je crois que cet outil permet de récupérer les flux sur 127.0.0.1

    http://www.nirsoft.net/utils/socket_sniffer.html

    Pas mal d'autres outils ici:

    http://www.nirsoft.net/utils/index.html#network_utils


    Paul Bacelar, Ex - MVP VC++

    vendredi 6 juin 2014 15:57
    Modérateur
  • J'ai essayé SocketSniffer mais ca ne fonctionne pas. L'outil ne voit pas mes processus.

    J'ai essayé RawCap. J'ai fait analysé le fichier pCap avec WireShark, mais je ne sais pas quelles informations rechercher. Avez-vous un conseil à me donner ?

    J'ai développé un petit outil (du type Iperf), pour reproduire le comportement de mon application.

    Cet outil se lance en mode serveur ou client, ce qui me permet de creer une socket TCP/IP entre 2 processus.

    Le processus Serveur, transmets au client une data de 6Mo toutes les 30ms, dès que le client se connecte.

    J'ai observé que sur le serveur A, la transmission mettait en moyenne ~4.5ms (avec SNDBUF & RCVBUF à 8Ko pour chaque socket). Cette durée moyenne de transmission a également été mesuré dans mon application principale.

    Sur le serveur B, la transmission mettait en moyenne 12ms (avec SNDBUF & RCVBUF à 8Ko pour chaque socket). Ce qui est étrange ici, c'est que chaque transmission variait entre 11ms et 13ms. Or dans mon application principale, seule une transmission sur 2 mettait ~11ms, les autres duraient ~70ms.

    Est-ce un problème dans mon processus qui recoit la donnée, qui est lent et donc retarde l'émetteur ?

    Ce que je trouve étrange est que le serveur B donne de moins bonne performance que le serveur A, sachant que le serveur A dispose d'un processeur moins puissant, moins de memoire et date de 2011, alors que le serveur B a été acheté en 2014.

    Peut-etre s'agit-il d'un problème de scheduling de processus (comme vous me l'indiquer dans votre 1er message) ?

    J'ai fait un test où j'ai changé l'affinité des 2 processus (Client&Serveur de mon outil de test) pour qu'ils soit exécuté sur la même CPU. Les performances non pas évoluées et j'avais toujours une durée moyenne de 12ms de transfert sur le serveur B.

    Merci pour les liens, je verrais ce que je peux faire  avec tous ces outils ?

    Avez-vous une idée sur quels types d'indices rechercher ?

    Merci de votre aide.

    vendredi 6 juin 2014 16:35
  • Bonjour

    Je dirais de poser la question sur un forum TechNet dédié à votre version Windows. Le plus probable les spécialistes ITPro pourront vous indiquer comment dépanner le problème.

    Bien cordialement,


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    mercredi 11 juin 2014 12:39
  • Mais je serais très intéressé par la réponse, donc si vous pensez à la mettre ici, ça serait trop cool. ;-)


    Paul Bacelar, Ex - MVP VC++

    jeudi 12 juin 2014 18:15
    Modérateur
  • Bonjour,

    J'ai réussi à améliorer les performances de mon serveur B (Double Xeon 2620), suite à cet article http://support.microsoft.com/kb/2207548/fr

    Le profil de gestion de l'alimentation paramétré dans l'OS du Serveur B n'était pas le même que celui du serveur A.

    Sur le serveur A le profil sélectionné était "Performances élevées".

    En changeant le profil de gestion de l'alimentation par le profil "Performances élevées", sur le serveur B, j'ai pu améliorer les performances de ce serveur et obtenir des durées d'appels à la fonction send de l'ordre de 8 à 9ms en continue.

    Cependant ce changement dans la configuration de l'OS ne semble pas suffisant, car les performances de mon application se dégradent dès lors que j'active l'enregistrement de données dans un fichier. Les temps de transferts d'une socket varie entre 10ms et 40ms.

    Je vais étudier :

    •     Les performances de mon processus Client, qui peut-être met trop de temps pour réceptionner les données de la socket et donc ralentir le processus Serveur.
    •     La configuration RAID 5 du serveur B qui a un equipement différente du serveur A.

    Merci à vous


    • Modifié Gawik mardi 17 juin 2014 13:27
    mardi 17 juin 2014 13:27
  • Merci à vous pour ce retour, et courage pour vos recherches.

    Paul Bacelar, Ex - MVP VC++

    mardi 17 juin 2014 15:48
    Modérateur
  • J'ai réalisé des tests avec l'applicatif iperf en lancant 2 commandes :

         iperf -s 127.0.0.1

         iperf -c 127.0.0.1

    J'ai observé sur mon serveur A (équipé d'un mono processeur Xeon 5620) les performances de transmission sont constantes ~4.6Gbits/s.

    En revanche sur mon serveur B (équipé d'un bi processeur Xeon E5-2620), les performances de transmission sont constantes ~5.1Gbits/s si les 2 processus sont exécutés sur la même CPU. Dès lors que l'un des processus iperf est exécuté sur la seconde CPU, les performances chutent à ~2.6Gbits/s.

    Est-ce un problème lié à l'architecture NUMA ?

    Il semblerait que NUMA peut avoir une impact négative sur les performances voir le forum Intel : https://software.intel.com/en-us/forums/topic/333444

    mardi 1 juillet 2014 13:31
  • Une architecture NUMA a clairement une influence sur les flux réseaux.

    Une architecture NUMA avec des cartes réseaux haut de gamme est un avantage, mais un inconvénient avec des cartes à 10€.

    Je ne suis pas un spécialiste réseaux, il faudrait voir sur les forums dédiés.

    En temps que dev, la solution de faire de l'affinité de CPU serait un quick-win :

    http://msdn.microsoft.com/en-us/library/windows/desktop/ms686223(v=vs.85).aspx

    http://msdn.microsoft.com/en-us/library/windows/desktop/ms686247(v=vs.85).aspx

    Mais avec un tel niveau de performance de communication locale, je me serait naturellement penché sur de la mémoire partagée entre les deux processus.


    Paul Bacelar, Ex - MVP VC++

    mardi 1 juillet 2014 14:35
    Modérateur