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

C++ Discussion :

gestion de buffer


Sujet :

C++

  1. #1
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut gestion de buffer
    Bonjour à tous,

    c'est plus une discussion qu'une question à proprement parler, mais j'aurais bien aimé avoir votre avis là-dessus:

    Le contexte:
    Une application temps réel, donc grosse contrainte de rapidité d'exécution. Pas de contraintes particulières sur la gestion de la mémoire ni la compilation.
    Plateforme: windows
    Compilateur: celui de visual 2005 (mais cela n'a pas d'importance je pense)
    Bibliothèque: STL si besoin est.

    La problématique:
    J'ai une boucle du type:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    while (!MustStop) //MustStop est modifié par un autre thread
    {
        int iBuffSize;
        short* source_buffer = GetBuffer(&iBuffSize);
     
        //Et là, je dois copier le buffer et faire des traitements sur la copie
    }
    - Je ne connais pas la taille du buffer que je vais récupérer avant chaque itération,et cette taille est variable.
    - La fonction GetBuffer(int &iBuffSize) me renvoie l'adresse du premier élément du buffer et me donne sa taille (iBuffSize).
    - Je dois absolument récupérer le buffer (le copier) car je ne dois pas modifier le buffer d'origine.

    Question
    Où et comment allouer le buffer dans lequel je vais copier mes données? Comment optimiser l'allocation?


    J'espère que je suis suffisamment clair. Si ce n'est pas le cas, je me ferais un plaisir de re-expliquer tout ça.

    Toute remarque est la bienvenue; merci pour votre participation

  2. #2
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Alors si tu vas récupérer que des short, tu peux utiliser une std::list de short, ou une std::deque. Enfin un conteneur standard quoi.
    Sinon, hmm ... ben moi j'utiliserais un conteneur standard

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    258
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 258
    Par défaut
    Comme d'habitude, tout dépend des traitements. Je te conseille de regarder des conteneurs standards, en choisir un en fonction des opérations que tu vas devoir faire dessus, et regarder si la vitesse d'exécution te suffit. Si c'est le cas, pas la peine de chercher plus loin, sinon tu es probablement bon pour recoder les conteneurs. Dans ce cas, si tu peux garder une interface similaire à la SL (itérateurs, nom des fonctions, ...), ça pourra être utile si tu veux ré-utiliser le code dans un autre projet.

  4. #4
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    En effet.
    Mais en principe les conteneurs standards sont assez rapides, donc à mon avis cela devrait suffir.
    Tiens nous au courant.

  5. #5
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Je commencerais par chercher à changer l'interface pour ne pas avoir besoin de copies. Normalement on a un pool de buffer et les threads se passent la propriété du buffer.

    Sinon,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    std::vector<short> myCopy;
    while (!MustStop) //MustStop est modifié par un autre thread
    // il faudrait alors ce qu'il faut pour être assuré que MustStop n'est pas
    // gardé en cache ou dans un registre...
    {
        int iBuffSize;
        short* source_buffer = GetBuffer(&iBuffSize);
     
        if (myCopy.size() < iBuffSize) {
           myCopy.resize(iBuffSize);
        }
        memcpy(&myCopy[0], source_buffer, iBuffSize*sizeof *iBuffSize);
        // je te laisse le traitement
    }

  6. #6
    mat.M
    Invité(e)
    Par défaut
    Citation Envoyé par r0d
    Plateforme: windows
    Faut prendre des API spécifiques Windows comme GlobalAlloc ;

  7. #7
    Membre expérimenté
    Avatar de David Fleury
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    253
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 253
    Par défaut
    <pinaillage>

    Le contexte:
    Une application temps réel, donc grosse contrainte de rapidité d'exécution. Pas de contraintes particulières sur la gestion de la mémoire ni la compilation.
    Plateforme: windows
    Le contexte et la plateforme sont rigolos.

    Le 'temps réel' suivi de 'donc ... contrainte de rapidité' est un raccourci
    à la mode alors on ne dira rien il est trop tard ce soir

    </pinaillage>

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 394
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    Citation Envoyé par mat.M
    Faut prendre des API spécifiques Windows comme GlobalAlloc ;
    Ici, je ne vois pas trop pourquoi...


    PS: Au passage, Windows n'est pas un "OS temps-réel".
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut
    Bonjour à tous,

    merci beaucoup pour vos interventions.
    Alors voici quelques précisions (et modifications).

    La boucle ressemblerait, en fait, plutôt à cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    while (!MustStop) //MustStop est modifié par un autre thread
    {
        int iBuffSize = GetSize(); //donc on connais la taille avant de récupérer le buffer
        float* source_buffer = GetBuffer(iBuffSize); //c'est un tableau de float finalement :s
     
       // le traitement, qui contient un appel du style:
       UneFonction(myCopy, iBuffSize); //qui modifie MyCopy, 
       // cette fonction fait partie d'une lib que je ne peux pas modifier.
       // Elle prend un float* en paramètre
    }
    Alors donc, que pensez-vous de ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    std::vector<float> myCopy;
    while (!MustStop) //MustStop est modifié par un autre thread
    //c'est géré en amont, je ne m'occupe pas de cela :)
    {
        int iBuffSize = GetBugffSize();
        float* source_buffer = GetBuffer(iBuffSize);
     
        if (myCopy.size() < iBuffSize) {
           myCopy.resize(iBuffSize);
        }
        memcpy(&myCopy[0], source_buffer, iBuffSize*sizeof *iBuffSize);
     
        UneFonction( (float*) myCopy, iBuffSize ); //ceci devrait fonctionner non?
    }

  10. #10
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut
    Sinon, pour le temps réeel, c'était un raccourci, en effet. Pour être plus précis, je devrais dire: il y a plusieurs threads qui tournent et effectuent des traitements. Chacun d'entre eux doit être le plus rapide possible car nous devons assurer une vitesse minimale de traitement, qui est celle du temps réel, et qui risque d'être difficile à assurer au vu du nombre important de tâches à accomplir.

  11. #11
    Membre chevronné
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 464
    Par défaut
    petit détail qui peut avoir son importance :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    float* source_buffer = GetBuffer(iBuffSize);
    serait avantageusement remplacé par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const float* source_buffer = GetBuffer(iBuffSize);
    pour :

    + de clarté,
    + de sécurité,
    + d'opportunités d'optimisations pour le compilateur.

  12. #12
    mat.M
    Invité(e)
    Par défaut
    Citation Envoyé par Médinoc
    Ici, je ne vois pas trop pourquoi...
    C'est très simple et cela s'explique aisément : si on utilise des fonctions Windows la gestion de la mémoire en sera meilleure car c'est l'OS qui détermine les stratégies à adopter ( allocation de pages ).
    cf "Programming Windows Nt" de Jeffrey Richter.
    Avec des simples new il n'est pas exclu que la mémoire se fragmente..
    Mais faut-il préciser que utiliser des API c'est seulement dans le cas de grosses allocations.
    Pour des petites allocations cela n'en vaut pas la peine..

    PS: Au passage, Windows n'est pas un "OS temps-réel".
    Je sais merci mais ça faut dire cela à R0d.
    Qu'il prenne un autre OS comme Qnx ou je ne sais quoi.

    Question
    Où et comment allouer le buffer dans lequel je vais copier mes données? Comment optimiser l'allocation?
    C'est exclusivement l'OS qui prend ça en charge...
    Tu pourras toujours faire un new et obtenir un pointeur sur une zone mémoire après l'OS va faire sa propre cuisine quoique tu fasses....

    while (!MustStop) //MustStop est modifié par un autre thread
    Voir les sections critiques , les API EnterCriticalSection et InterlockIncrement

Discussions similaires

  1. [68302][HDLC] Gestion des buffers incohérentes
    Par transgohan dans le forum Embarqué
    Réponses: 1
    Dernier message: 28/01/2015, 10h18
  2. [PHP 5.3] Gestion des buffers (ob_start)
    Par hornetbzz dans le forum Langage
    Réponses: 4
    Dernier message: 18/10/2010, 16h23
  3. gestion buffer dans gtktextview
    Par coax81 dans le forum GTK+ avec C & C++
    Réponses: 2
    Dernier message: 25/06/2007, 13h50
  4. Gestion de buffer
    Par Treuze dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 26/04/2007, 14h08
  5. Gestion des buffers dans une fonction
    Par JiJiJaco dans le forum Langage
    Réponses: 2
    Dernier message: 06/01/2006, 11h20

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