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

SL & STL C++ Discussion :

Conteneur pour optimisation de temps de calcul


Sujet :

SL & STL C++

  1. #1
    Membre habitué
    Homme Profil pro
    Doctorant en Astrophysique
    Inscrit en
    Mars 2009
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Astrophysique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2009
    Messages : 312
    Points : 176
    Points
    176
    Par défaut Conteneur pour optimisation de temps de calcul
    Bonjour.

    J'ai un niveau de C++ "moyen" (je maitrise bien l'utilisation de classes, de librairies comme Qt, mais je n'ai aucune expérience dans la programmation "avancée" style métaprogrammation). Je travaille actuellement sur un programme de calcul pour un problème de physique et je me suis rendu compte que la manière dont je l'avais implanté la première fois ramais à mort car la classe contenant les algos de calcul faisait appel à des dizaines d'autres classes pas forcément optimisée et qu'au final ça ramait à mort.

    J'ai donc pensé qu'il serait mieux de mettre toutes les données et variables temporaires dont la classe d'algo à besoin en variables membres pour éviter qu'elle fasse appel à des dizaines d'autres classes, et d'inliner certaines fonctions de cette classe. Est-ce la bonne solution ?

    Ensuite voilà mon problème : du coup le nombre de variables membres "double" de la classe a exploser (je dois en être à plus de 100) et ça m'aiderait bien si je pouvais les répartir dans des conteneurs. C'est un peu complexe mais ma classe peut faire des calculs relatifs à 4 entités physiques du coup j'ai 4 fois les "mêmes" variables. Si je pouvais plutôt classer ça dans un conteneur type vector de taille 4, ce serait plus cool. L'autre problème est que certaines de ces variables sont des vecteurs physiques (type x,y,z) donc si je voulais classer ça proprement, je devrai faire un vector de vector.
    Par exemple [0][0] serait la composante x pour la première entité physique, [0][1] la composante y, [0][2] la composante z, [1][0] la composante x pour la seconde entité physique etc...

    Ma question est la suivante : avec quel conteneur travailler ?
    A priori la taille ne variera pas (très petite taille) et j'ai besoin d'un accès optimisé (d'un point de vue temps) en lecture et en écriture de n'importe quelle composante.

    (j'ai lu la faq, je comptais utiliser des vector, mais je ne suis pas certain que des vector de vector soient le mieux lorsque j'aurai besoin d'un double classement)

    Précision : l'optimisation n'est pas super critique non plus, mais disons que si j'ai un facteur 2 sur le temps de calcul ça commence à devenir important.

    Merci beaucoup

    EDIT : petite précision : en fait je n'ai pas besoin d'utiliser des opération de tri etc... : c'est juste pour clarifier mon code et avoir 25 variables membres au lieu de 100...

  2. #2
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 534
    Points : 6 723
    Points
    6 723
    Par défaut
    Bonjour,

    attention, il est plus lent d'accéder à des éléments d'un vecteur stl qu'à des membres d'une structure/classes. De plus ainsi votre code va devenir illisible et peu maintenable => les problèmes empireront avec le temps

    il y a beaucoup de raisons qui peuvent rendre un programme lent, en dehors des raisons d'algorithmie pure un code est lent parce que le code exécuté n'est pas directement utile pour produire le résultât mais passe par des méandres genre multiple recopies/allocations/libérations (par exemple lié à des passages de données par valeur et non par référence), mauvais choix de structure de mémorisation (par exemple utilisation d'un vecteur stl et non d'une liste alors qu'il y a constamment des ajouts/retraits dans la collection, ou recherches continuelles dans un vecteur/liste classique à la recherche d'un élément alors qu'une map aurait pu être utilisée). Ne pas rendre inline les getter (et même les setter ne faisant qu'un affectation bête) ralenti aussi, même si ce n'est pas là que la perte de temps est la plus grande.

    avez-vous fait du profiling (genre g++ -pg si vous n'avez pas d'autre outils) ?

  3. #3
    Membre habitué
    Homme Profil pro
    Doctorant en Astrophysique
    Inscrit en
    Mars 2009
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Astrophysique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2009
    Messages : 312
    Points : 176
    Points
    176
    Par défaut
    EDIT : je viens d'essayer le profiling sur une ancienne version du problème et c'est bien la classe d'algo qui est d'une lenteur extrême.
    Ce que je prévois de faire c'est d'initialiser la classe d'algo avec mes anciennes classes, que la classe d'algo stocke tout ce qui lui faut dans des variables membres et qu'ensuite elle fasse les calculs "en interne" sans avoir besoin d'accéder sans cesse à d'autres classes.

    Mon problème est le suivant : pour faire ce que j'ai décrit précédemment j'ai fait exploser le nombre de variables membres de type double (des intermédiaires de calcul) : j'ai recompté et j'en ai environ 400. Du coup, honnêtement, ça rend vraiment les choses indébuggables, complètement obscures, mais sans doute très rapides (j'ai pas essayé à la compilation parce que je n'ai pas terminé mais bon). En stockant mes variables dans des vectors (ou un autre conteneur) le code gagnerait énormément en clarté et en lisibilité. J'ai par exemple besoin de 4 double (énergie d'anisotropie de 4 macrospins) :
    m_c1eani;
    m_c2eani;
    m_c3eani;
    m_c4eani;
    Si je stockais ça dans un conteneur de taille 4 en appelant ça m_eani, ça serait vachement plus lisible dans le code. Mais quel conteneur utiliser ?

  4. #4
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 534
    Points : 6 723
    Points
    6 723
    Par défaut
    désolé mais présenté ainsi cela ressemble à un grand n'importe quoi

    votre première réponse avant édition était que les résultât du profiling étaient étranges, c'est à dire ?

    il est cependant bien difficile de plus vous aidez si vous ne publiez pas de code que l'on pourrait regarder ...

  5. #5
    Membre chevronné
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Points : 1 921
    Points
    1 921
    Par défaut
    Citation Envoyé par bruno_pages Voir le message
    attention, il est plus lent d'accéder à des éléments d'un vecteur stl qu'à des membres d'une structure/classes.
    Si peu.

    je pense surtout que le code du PO est peu cache-friendly.

    Et si la taille est fixe, boost::array

  6. #6
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 629
    Points : 30 692
    Points
    30 692
    Par défaut
    Salut,

    Si tu as un nombre fini de données, il n'y a rien à faire, l'accès aléatoire aux information proposé par un tableau est le plus rapide, si tu a les moyen de déterminer l'indice de la donnée qui t'intéresse...

    De plus, il est assez facile de déduire une formule permettant de récupérer x, y ou z, si on considère que les informations sont d'office placées dans cet ordre dans un tableau:

    Si x y et z sont de même type (pour l'exemple, considérons que ce sont des doubles ), et que tu as 100 vecteurs à représenter, tu peux envisager de créer un tableau tab de... 300 double dans lequel la valeur x du premier vecteur est tab[0], la valeur y est tab[1] et la valeur z est tab[2] (respectivement tab[3],tab[4] et tab[5] pour le deuxième élément et ainsi de suite...)

    Les formules de calcul d'indice sont donc relativement simples:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Pour calculer la position de la valeur X du vecteur V : V*3
    pour calculer la position de la valeur Y du vecteur V : V*3+1
    pour calculer la position de la valeur Z du vecteur V : V*3+2
    A partir de là, tu peux parfaitement, au choix, utiliser un objet de type std::vector, mais tu peux aussi (bien que, bon, tu dois être conscient des limitations de chacune des possibilité) envisager l'utilisation d'un "simple" tableau C style de taille fixe, ou celle d'un tableau C style de taille dynamique..

    Toujours pour un tableau de 100 vecteurs, cela donnerait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    /* le tableau C style de taille fixe */
    double tabFixe[300];
    /* le tableau C style de taille dynamique */
    double *tabDyn=new double[300]; /* n'oublie pas delete[] tabDyn quand tu
                                     * n'en a plus besoin :D
                                     */
    /* le beau tableau C++ */
    std::vector<double> tabCpp(300); /* l'un des constructeurs de
                                      * vector permet de préciser le nombre d'éléments
                                      * qu'il contient :D
                                       */
    A partir de là, l'accès se ferait de la même manière sous la forme d'un simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /*accéder à la valeur X du 15eme vecteur */
    double x=tabCpp[14*3];
    /* accéder à la valeur Y du 30eme vecteur */
    double y=tabDyn[14*3+1];
    /* accéder à la valeur Z du premier vecteur */
    double z=tabFixe[2]; /* en fait: 0*3+2 :D */
    Maintenant, cela implique que les différents vecteurs soient déjà triés... Et c'est, peut être en fait justement ton problème

Discussions similaires

  1. solution pour optimiser le temps de calcul (Cluster +2008 )
    Par iMech dans le forum Windows Serveur
    Réponses: 0
    Dernier message: 01/03/2015, 20h34
  2. Réponses: 6
    Dernier message: 11/03/2009, 11h26
  3. optimisation du temps de calcul
    Par deubelte dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 27/08/2007, 14h31
  4. optimisation du temps de calcul
    Par mhamedbj dans le forum Langage
    Réponses: 4
    Dernier message: 14/03/2007, 16h08

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