IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MFC Discussion :

[pipe nommés][multithreading]probleme de vitesse !!!?!


Sujet :

MFC

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 35
    Points : 31
    Points
    31
    Par défaut [pipe nommés][multithreading]probleme de vitesse !!!?!
    Bonjour,

    Je suis depuis quelques temps confronté à un probleme et je n'arrive pas à mettre le doigt sur la source d'"erreur". J'ai développé recemment un serveur de communication et une bibliothèque cliente basée sur les pipes nommés windows. Le but étant de communiquer en temps réel entre les clients les valeurs de différentes variables dès leur changement.

    La problèmatique est que je n'obtiens pas les performances prévues...
    En effet le serveur ne réussi à transmettre qu'un message toutes les 30 ms (message et réponse de l'autre client). En regardant le gestionaire de taches, je peux remarquer que le processeur n'est absolument pas sollicité.
    Le fait le plus troublant est que si je refais le même test avec une page web en flash ou un exe flash ouvert, les performances sont 10 à 12 fois supérieure!!!

    J'ai donc pensé pendant un moment à un ralentissement du à mes traces sur la console (ah oui, les clients et le serveur sont en mode console), en imaginant, que flash pouvait lancer une quelquonque acceleration materielle de l'affichage. Cependant, même en supprimant les traces, le problème persiste. Peut-être est-ce un problème d'ordonnacement? portaant il me semble que mes sections critiques sont protégées au mieux et que les temps de suspension de thread sont minimums...

    A titre d'information, les clients ainsi que le serveur sont entièrement développés de manière parallèle:
    Le serveur possède 3 threads par client connectés: un qui lit sur le pipe et empile les messages dans une file d'attente, un qui redirige les messages dans la file d'attente d'envoi de message du client destinataire et un qui dépile les messages et les ecrit dans le pipe du destinataire. (architecture classique...)

    La bibliothèque possède 2 threads: un qui lit le pipe et empile les messages dans une liste de reception et un qui dépile la liste d'envoi de message et écrit lesdits messages sur le pipe. (classique aussi)

    Si une personne a déjà expérimenté ce genre de problème, je suis tout ouie pour les conseils que vous pourriez me donner.

    visual'ment,
    Yverain.

  2. #2
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    salut,
    etonnant ,
    je pense qu'il faudrait que tu testes cette eventuelle lenteur dans un contexte simplifié pour verifier si c'est le pipe nommé qui rame ou si c'est l'implementation qui le ralentit....
    dans un post precedent j'avais posté ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
     
    // server
    #include "iostream.h"
    #include <process.h>
    void msnpClientThread(HANDLE msnPipe)
    {
        char textBuffer[128];
        DWORD numBytesRead;
        DWORD numBytesWritten;
     
        while(1)
        {
            if(!ReadFile(msnPipe,textBuffer,128,&numBytesRead,(LPOVERLAPPED)NULL))
            {
                cerr << "error:unable to read from named pipe" << endl;
                break;
            }
            _strupr(textBuffer);
            if(!WriteFile(msnPipe,textBuffer,strlen(textBuffer)+1,&numBytesWritten,(LPOVERLAPPED)NULL))
            {
                cerr << "error:unable to write to named pipe" << endl;
                break;
            }
            cout << textBuffer <<endl;
        }
        FlushFileBuffers(msnPipe);
        DisconnectNamedPipe(msnPipe);
        CloseHandle(msnPipe);
    }
    #define MAX_INSTANCES 3
    void mainServer()
    {
        HANDLE msnPipe;
        DWORD msnpThread;
        while(1)
        {
            msnPipe=CreateNamedPipe("\\\\.\\pipe\\msnp",PIPE_ACCESS_DUPLEX,PIPE_TYPE_BYTE | PIPE_WAIT,
                                    MAX_INSTANCES,0,0,150,(LPSECURITY_ATTRIBUTES)NULL);
     
            if(msnPipe== INVALID_HANDLE_VALUE)
            {
                cerr << "Error: Unable to create a named pipe " << endl;
                continue;
            }
     
            if(!ConnectNamedPipe(msnPipe,(LPOVERLAPPED)NULL))
            {
                cerr << "Error: Unable to connect a named pipe " << endl;
                CloseHandle(msnPipe);
                return ;
            }
            msnpThread = _beginthread(msnpClientThread,0,(HANDLE)msnPipe);
            if(msnpThread==-1)
            {
                cerr << "Error : Unable to create Thread " << endl;
                CloseHandle(msnPipe);
            }
        }
    }
    // client
    void mainClt()
    {
        HANDLE msnPipe;
        DWORD numBytesRead;
        DWORD numBytesWritten;
        char textToSend[128];
        char textRecvd[128];
        char machineName[80];
        char pipeName[80];
     
        cout << "enter Name of server machine";
        cin >> machineName;
        wsprintf(pipeName,"\\\\%s\\pipe\\msnp",machineName);
        msnPipe=CreateFile(pipeName,GENERIC_READ | GENERIC_WRITE,0,
                (LPSECURITY_ATTRIBUTES)NULL,
                OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,(HANDLE)NULL);
        if(msnPipe==INVALID_HANDLE_VALUE)
        {
            cerr << "Error: Unable to connect a named pipe " << endl;
            return ;
        }
        while(1)
        {
            cout << "type text to send:";
            cin.getline(textToSend,128);
            if(!WriteFile(msnPipe,textToSend,strlen(textToSend)+1,&numBytesWritten,(LPOVERLAPPED)NULL))
            {
                cerr << "error:unable to write to named pipe" << endl;
                CloseHandle(msnPipe);
                return ;
            }
            if(!ReadFile(msnPipe,textRecvd,128,&numBytesRead,(LPOVERLAPPED)NULL))
            {
                cerr << "error:unable to read from named pipe" << endl;
                CloseHandle(msnPipe);
                return ;
            }
            cout << "Received :" << textRecvd << endl;
        }
    }
    adaptable pour tester la connexion .


  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 35
    Points : 31
    Points
    31
    Par défaut
    non, en fait j'ai déjà testé pour les lectures écritures de pipe, et j'obtiens toujours 0 ms pour toutes les opérations....

    NB: mes messages sont des paquets de taille fixe de 220 octets.

    En fait, j'ai mesuré unitairement le temps de toutes mes fonction; j'obtiens toujours 0ms de temps d'execution (pour lire puis empiler, dépiler et écrire...etc).
    Il semblerait que ce soit un temps de latence, un mauvais ordonnancement dans mes threads, pourtant, encore une fois, je ne trouve pas de zone de ralentissment dues à mes sections critiques!!!

    Le fait de lancer flash augmente de manière considérable l'utilisation du processeur par mes process, comme si mon prog était fainéant, mais qu'il retrouvait du poil de la bête quand on lance flash!!!

    En tous cas merci.
    Yverain

  4. #4
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    comment tu suspends tes threads ?

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 35
    Points : 31
    Points
    31
    Par défaut
    En fait, j'ai une section critique par file:
    j'entre dans ma section critique quand j'empile (quand je reçois un message) et quand je dépile (quand j'envoi un message)...

  6. #6
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Tu as du code d'IHM dans tout ça ?
    Note que tous ces thread je trouve ça un peu usine à gaz. Pourquoi 3 thread par client sur le serveur ? Le thread qui lit le pipe peut pas envoyer directement sur le client qui va bien ? Avec un seul thread pour tous les clients ? Si l'écriture blocante du pipe te gêne utilise le mode overlapped, l'écriture ne sera plus blocante.

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 35
    Points : 31
    Points
    31
    Par défaut
    Je suis dans le cadre d'informatique industrielle et supervision, le fait est que je dois répondre en presque temps réel (Je sais, pas de remarque sur windows pour le temps réel...) à de grosses sollicitations.. et le fait d'avoir 3 thread permet un empilement au niveau d'une file (liste chainée) qui est de taille infinie, contrairement au buffer du pipe nommé qui est fini et qui ne bloque, contrairement à ce que les gens pensent, qu'en écriture. Le fait d'avoir un pipe non bloquant en écriture et de taille finie implique, si on fonctionne sur un seul thread entraine une perte partielle des messages (en fait 20% de pertes dans l'ancienne architecture que j'ai reprise).

    En effet, le fait de faire une lecture sur un thread se résume a effectuer séquentiellement la tache:

    lecture
    -
    traitement
    -
    écriture

    si les opérations de lecture écriture sont de durée fixe (car les messages sont de taille fixe), le traitement quant à lui est de durée variable car il est souvent l'occasion d'accès à un programme et pendant ce traitement, les clients envoient encore des données.

    Ceci induit donc la deuxième problèmatique du serveur de communication; Le serveur de communication fonctionnant de manière synchrone (une requète induit obligatoirement une réponse) sur des opérations de lecture écriture, il est nécéssaire de pouvoir hautement paralléliser les traitement afin d'obtenir une disponibilité maximum.

    Si on rajoute à ça l'existance de "triggers" sur le server, qui envoient des messages de modification de valeurs du serveur au clients, et ce de manière asynchrone (un message n'induit pas de réponse), on comprend alors tout l'intérêt de la multiplication des threads.

    En résumé, les tests effectués démontrent que plus les taches susceptibles de pénaliser les performances de l'outil de comm sont parallèlisées, plus le serveur de comm est performant.

    Maintenant, la question est de savoir ce qui pénalise mon serveur, et pourquoi une interraction avec le logiciel flash le boost, mais mes connaissance actuelle ne mon pas permis de mettre le doigt sur la solution.

    Ma dernière théorie en date était que les temps de repos(Sleep uniquement) était trop court, et que le process passait en NOPE puis reprennait la main de suite, sans faire de changement de thread. et que le fait de lancer flash, de priorité plus élevée finissait par forcer ces changements de thread.

    Capilotracté n'est il pas.... et totallement incorrect...

    J'ai completement usé mes cellules grises, je vais me pendre de suite!!!

    Danke, thanks
    Yverain

  8. #8
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    ou tu utilises des sleeps et dans quel but (possible que le probleme vienne de la ) ?

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 35
    Points : 31
    Points
    31
    Par défaut
    j'utilise des slips (désolé)quand je suis dans les cas ou je dois sauvegarder du temps processor, par exemple lors des boucles de lecture:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    tant que pipe_ouvert
        taille = lecture(message);
        si taille > 0 alors
             empiler(message,pile_lecture);
        sinon
            Slip(1ms);
        Fin si
    fin tant que
    des boucles d'écriture:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    tant que pipe_ouvert
        si non pile_est_vide alors
        message = depiler(pile_ecriture)
        ecriture(message );
        sinon
            Slip(1ms);
        Fin si
    fin tant que
    des boucles de traitement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    tant que pipe_ouvert
        si non pile_est_vide alors
        message = depiler(pile_lecture)
        reponse = traiter(message );
        empiler(reponse,pile_ecriture);
        sinon
            Slip(1ms);
        Fin si
    fin tant que
    voili voilou...

    normalement, en cas de charge, le CPU doit être entierement utilisé... mais ce n'est pas le cas... le probleme est qu'il y a encore une surcouche avec la partie connexion au progiciel et qu'en fait , le nombre de taches parallèles est sommes toute assez important.

  10. #10
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    contrairement au buffer du pipe nommé qui est fini et qui ne bloque, contrairement à ce que les gens pensent, qu'en écriture
    Par défaut. Mais Windows supporte la lecture / écriture asynchrone. Dans ce mode, un ReadFile / WriteFile rendra tout de suite la main, et ta demande de lecture / écriture sera mise en attente, dans une file, gérée par Windows...
    http://msdn.microsoft.com/library/en-us/ipc/base/synchronous_and_overlapped_input_and_output.asp
    Tu as plusieurs techniques.
    http://www.sysinternals.com/Information/IoCompletionPorts.html
    http://www.codeproject.com/internet/IOCompletionPort.asp
    http://www.codeproject.com/internet/IOCP_Server_client.asp


    il est nécéssaire de pouvoir hautement paralléliser les traitement afin d'obtenir une disponibilité maximum.

    Si on rajoute à ça l'existance de "triggers" sur le server, qui envoient des messages de modification de valeurs du serveur au clients, et ce de manière asynchrone (un message n'induit pas de réponse), on comprend alors tout l'intérêt de la multiplication des threads.
    oui mais faut pas trop créer de threads quand même, car ça coute à force.

    Maintenant, la question est de savoir ce qui pénalise mon serveur, et pourquoi une interraction avec le logiciel flash le boost, mais mes connaissance actuelle ne mon pas permis de mettre le doigt sur la solution.
    A priori pas de raison. A part au niveau du code d'IHM je vois pas trop. C'est pour ça que je te demande:
    - as-tu du code d'IHM ? A quel niveau ?
    En tous cas, AMHA, l'erreur est d'avantage dans ton code que dans celui de l'ordonnanceur de Windows.

    j'utilise des slips
    ça fonctionne comment ? Normalement tu n'en n'as pas besoin.

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 35
    Points : 31
    Points
    31
    Par défaut
    En tous cas, AMHA, l'erreur est d'avantage dans ton code que dans celui de l'ordonnanceur de Windows.
    la dessus, on est d'accord, mais le fait que l'appli accelere quand flash est lancé doit normalement nous donner un indice sur la raison de la lenteur. Je me posais donc des questions sur la façon dont fonctionnait l'ordonnanceur. En effet, tous les tests effectués montre que le temps de latence est du à des temps d'inactivité du processus...

    - as-tu du code d'IHM ? A quel niveau ?
    non, tout fonctionne en mode console de la même manière qu'avec un IHM, je m'étais posé la question moi aussi.

    Pour ce qui est des Sleep(slip), je suis obligé dans avoir au moins dans les boucles d'écriture. sinon, j'utilise 100% du cpu et c'est pas top.

    Pour le pipe overlapped, je connais,mais la specification fonctionnelle du systeme dans lequel j'integre le serveur de communication m'impose de travaille en mode synchrone sur la majorité des écritures.(NB: je n'utilise les pipes qu'en local d'ailleur), et en termes de performances, c'est pas forcement ce que j'attends....
    En fait mon client passe vraiment un grand nombre de demande (de l'ordre de 1 ou 2 à la ms en cas de cascade) et, même si le pipe est configuré en bloquant aucune des écritures n'est bloquée quand le pipe atteind sa taille maximal (65635 o il me semble, à vérifier dans la msdn) d'ou un écrasement des données si le pipe n'est pas vidé tout de suite.(à véifier pour le pipe overlapped, ce que je vais faire de ce pas...)

  12. #12
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    A chaque Sleep( 0 ) tu paumes 10 ms.

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 35
    Points : 31
    Points
    31
    Par défaut
    mais si je ne les fais pas, le probleme c'est que je bouffe toutes les ressources processeur

  14. #14
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 35
    Points : 31
    Points
    31
    Par défaut
    je viens de voir...

    Sleep(0) ne te fais pas perdre de temps...
    Il sert à reprendre le processeur/ordonnanceur, et fait bourriner le process(cf msdn)

    Sleep( 1) je te l'accorde, à une latence supèrieure à 1 ms. mais est nécessaire...

  15. #15
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 35
    Points : 31
    Points
    31
    Par défaut j'ai essayé en synchronisant
    ...tout avec des events, et il semblerait que ça marche... il me reste juste un léger interbloquage, mais ça je devrais trouver seul 8)

    En tous cas merci pour votre aide et à bientôt
    Yverain

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. probleme avec ecriture de pipe nommé
    Par Rhapso59 dans le forum C
    Réponses: 0
    Dernier message: 24/04/2009, 16h24
  2. Problème de vitesse lors de recherche de carré magique
    Par niniwizard dans le forum Prolog
    Réponses: 22
    Dernier message: 16/01/2009, 13h11
  3. Probleme de vitesse de transfert ..
    Par Nemesys dans le forum Hardware
    Réponses: 8
    Dernier message: 23/05/2006, 16h08
  4. Problème de vitesse de tranfert USB
    Par HNT dans le forum Matériel
    Réponses: 10
    Dernier message: 15/04/2006, 14h55
  5. Réponses: 3
    Dernier message: 16/03/2004, 16h42

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo