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 :

Au sujet du Code Bloat


Sujet :

C++

  1. #1
    Invité
    Invité(e)
    Par défaut Au sujet du Code Bloat
    Bonjour,

    Je récris actuellement un gros programme, en modifiant du code existant. J'utilise le même environnement et le même compilateur, mais je constate un accroissement rapide de la taille de mon exe. En gros, un programme qui faisait hier 3 Mo en fait aujourd'hui 9, alors que le nombre total de ligne de codes n'a pas changé (il a en fait baissé).

    Actuellement, je soupconne fortement la STL. J'utilise pas mal de vector<> sur des types utilisateurs. Comme toute la STL est template, cela signifie beaucoup d'instanciation, mais quand même un triplement du code à fonctionnalités égales?

    Avez vous rencontré ce genre de problème? la STL est elle réellement coupable? Comment peut on le résoudre (je n'ai pas du tout envie de finir avec un exe de 20Mo, 5 c'est déjà bien trop...)

    Merci d'avance,
    Francois

  2. #2
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Y a-t-il beaucoup de vecteurs sur des types vraiment différents(1) ? En théorie, ça pourrait expliquer, même si j'avoue avoir du mal à croire que ça pourrait être aussi impactant... Tu as essayé d'ajouter pour le plaisir un bout de code qui ne fait rien d'autre que d'instancier un vector sur une dizaine de types crées pour la circonstance, histoire de mesurer un delta ?

    Un gros accroissement peut apparaître la première fois que l'on utilise les flux dans un programme, mais ce devrait être one shot.

    Tu utilises quel compilateur ? Quelles options d'optimisation ?

    (1) : Par vraiment différent, je veux dire qu'une bonne implémentation n'aura pas de code bloat supplémentaire pour un vector<B*> si le programme contient déjà un vector<A*>, et on peut espérer que dans le futur, ce soit aussi vrai avec les vector<shared_ptr<A>> et vector<unique_ptr<A>>.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  3. #3
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Y a-t-il beaucoup de vecteurs sur des types vraiment différents(1) ?
    Tout à fait... Il doit y avoir une petite centaine de structures distinctes, au total, et des vecteur sur presque chacune. Avec des structures arborescentes de vecteurs de vecteurs...

    Citation Envoyé par JolyLoic Voir le message
    En théorie, ça pourrait expliquer, même si j'avoue avoir du mal à croire que ça pourrait être aussi impactant... Tu as essayé d'ajouter pour le plaisir un bout de code qui ne fait rien d'autre que d'instancier un vector sur une dizaine de types crées pour la circonstance, histoire de mesurer un delta ?
    Je vais effectivement essayer, et poster mes trouvailles sur ce fil, je pense que c'est utile... Pour l'instant, j'ai fait un essai sur un tout petit module (150 lignes de code). Le code était du calcul très proche du C, mais à la fin, pour je ne sais quelle raison, j'avais mis un fill_n (donc un algorithme de la stl)... un seul...

    Avec fill_n : code généré ds l'obj: 7k
    Sans fill_n : code généré 2k

    (cependant, enlever un fill_n par ci par la dans les autres modules représente un petit gain, mais pas aussi spectaculaire, ce serait trop facile!)

    Morale provisoire, il y a clairement un coût d'entrée de la STL au niveau du module. Je soupconne que l'un des effets indirects des templates est que le compilateur reinstancie tout ce dont il a besoin pour chaque module, et ca peut être un peu lourd...

    Citation Envoyé par JolyLoic Voir le message
    Un gros accroissement peut apparaître la première fois que l'on utilise les flux dans un programme, mais ce devrait être one shot.
    Des flux j'en avais avant, donc ca ne peut être cela.

    Citation Envoyé par JolyLoic Voir le message
    Tu utilises quel compilateur ? Quelles options d'optimisation ?
    Borland C++ Builder 6.0, options vitesse maxi (mais j'ai aussi teste l'option "debug", sans différence notable), et une STLPort fournie avec le compilateur (donc optimisé, pourrait on croire)

    Francois

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Fais attention au fait que BCB 6 revendiquait ne pas respecter le standard (et pas uniquement pour la VCL)...

    Il n'est donc absolument pas impossible que la version STL port ne soit pas aussi bien optimisé que ce que tu ne semble croire

    Il *semblerait* que les nouvelles versions de BCB tentent de mieux respecter la norme (mais je ne peux absolument pas donner de certitudes sur le sujet)

    Ceci dit, il serait intéressant de vérifier sur plusieurs modules (inter) dépendants du premier module sur lequel tu as testé les changements...

    *Peut-être* auras tu la chance que seul le module testé ne présente un tel accroissement de poids

    Enfin, es-tu sur d'avoir utilisé les mêmes options de compilation

    Généralement, on observe effectivement un accroissement (parfois considérable) du poids de l'exécutable en mode débug, du fait de la présence de toutes les informations nécessaires au débuggage, par rapport à la version release...

    Mais certaines options de compilations ou certaines habitudes de programmation (comme l'inlining implicite ou explicite de fonction qui ne devraient pas l'être) peuvent également avoir un impact fort malsain sur le poids de l'exécutable ([EDIT]et force est d'avouer que l'utilisation de template de facto l'inlining des fonctions template [/EDIT])
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Fais attention au fait que BCB 6 revendiquait ne pas respecter le standard (et pas uniquement pour la VCL)...
    Est ce un problème de standard? Il me semble que celui ci ne parle pas beaucoup de la taille des executables, laissé au compilateur... Ce qui me travaille, c'est que BCB, que j'utilise depuis longtemps, produit en général des exes pas trop gros, sauf dans certains cas précis (appels OLE typiquement).

    Citation Envoyé par koala01 Voir le message
    Ceci dit, il serait intéressant de vérifier sur plusieurs modules (inter) dépendants du premier module sur lequel tu as testé les changements...
    En fait, c'est après avoir modifié pas mal de choses que j'ai constaté ce triplement de taille. On avait un code de 3-4Mo environ (pour environ 35 000 lignes de code utilisateur, ie sans les librairies externes), répartis dans 75 modules environ. Pour l'instant seuls les principaux modules ont été touchés par la réorganisation, mais le code approche les 9Mo.

    Je vais essayer de rajouter des modifs similaires à celles faites récemment, et voir l'augmentation...

    Citation Envoyé par koala01 Voir le message
    Enfin, es-tu sur d'avoir utilisé les mêmes options de compilation
    Oui, en fait, j'ai fait les calculs de comparaison en mode debug et en mode release, sur l'ancien et le nouveau source... Il peut bien sur y avoir une subtilité qui m'échappe, mais j'en doute un peu... (j'observe en fait la hausse lors de modification successives de mon code, sans changement des options)

    Citation Envoyé par koala01 Voir le message
    Généralement, on observe effectivement un accroissement (parfois considérable) du poids de l'exécutable en mode débug, du fait de la présence de toutes les informations nécessaires au débuggage, par rapport à la version release...
    Oui, mais chez borland, j'ai repéré que l'augmentation se traduisait au niveau des .obj (modules compilés avant reliure), mais que le relieur avait le bon gout de supprimer ces éléments de l'exe pour les mettre dans un fichiers "annexe" (le tds) utilisé par le debuguer. Du coup, l'exe en mode débug n'est pas vraiment plus gros, voire légèrement plus petit que celui en mode release.

    Je comprends que Microsoft suit une voie très différente.

    Citation Envoyé par koala01 Voir le message
    Mais certaines options de compilations ou certaines habitudes de programmation (comme l'inlining implicite ou explicite de fonction qui ne devraient pas l'être) peuvent également avoir un impact fort malsain sur le poids de l'exécutable
    C'est mon hypothèse de travail. Je vais continuer à regarder, et essayer de raconter cela sur ce fil. Je soupconne que la situation est assez générique pour n'être pas qu'un pb borland...

    En attendant, merci beaucoup pour ces réponses, ça m'aide pas mal.

    Francois

  6. #6
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par fcharton Voir le message
    Oui, mais chez borland, j'ai repéré que l'augmentation se traduisait au niveau des .obj (modules compilés avant reliure), mais que le relieur avait le bon gout de supprimer ces éléments de l'exe pour les mettre dans un fichiers "annexe" (le tds) utilisé par le debuguer. Du coup, l'exe en mode débug n'est pas vraiment plus gros, voire légèrement plus petit que celui en mode release.
    Ce ne sont pas tant les informations de debug que le fait que l'inlining ne soit pas possible qui modifie le plus la taille des exécutable debug, surtout avec un style de programmation où plein d'appels de fonctions s'imbriquent comme le template metaprogramming pousse à le faire. J'ai déjà eu des explosions de stack en debug, alors qu'en release, j'en était très loin, avec boost.serialization, par exemple.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  7. #7
    Inactif  
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 138
    Par défaut
    Peut-être as-tu un léger problème de conception dans ton programme...

    Moi j'utilise Visual c++ et j'ai toujours eu l'impression que les exécutables étaient particulièrement optimisés en taille (même avec l'option "vitesse maximale").

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 537
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 537
    Par défaut
    Non mais il y a forcément un truc qui débloque.

    Pour générer 6Mo de rab au niveau de l'exécutable, ou bien du fait dans la métaprogramation très massive (template récursives, ce genre de trucs), ou bien tu as soucis dans le compilo.

    A mon avis tu as une option de compilation qui fait exploser la taille de ton exe. C'est ce qui me parait le plus probable.

  9. #9
    Invité
    Invité(e)
    Par défaut
    Je ne crois pas que ce soit une option de compilation: j'ai fait l'essai avec les mêmes options (sur les deux versions du code, avant et après), et pour plusieurs jeux d'options (de debug à optimisé...)

    Maintenant, et après un peu d'analyse je commence à mieux comprendre.

    Effectivement, toute l'augmentation ne venait pas du code. Une partie venait apparemment de ressources (images en fait) stockées de façon différentes dans les deux programmes (l'une inefficace...).

    En ce qui concerne le code, j'ai commencé à faire la chasse à la STL inutile, dans les headers d'abord, puis les algorithmes qui n'apportent rien (typiquement fill et copy sur types natifs), puis les types utilisateurs redondants (structures identiques définis comme classes différentes, et STL dessus), et enfin les conteneurs inutiles (vecteur de taille fixe et connue à la compilation, ce genre de choses).

    Sur les seules parties de codes modifiées cette semaines (quelques centaines de lignes réécrites, je pense), j'arrive à une baisse de 10% de la taille de l'exe... Voire, sur des fonctions appelées souvent, l'élimination de la STL se traduit souvent par un gain de performance...

    Je commence à douter de l'efficacité (au moins dans l'environnement que j'utilise) de la STL, en terme de vitesse et de taille de code produit. C'est bien évidemment un excellent outil de prototypage, mais sur du vrai code qui tourne vite?

    Francois

  10. #10
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Même si elles pourraient en être capables, je ne connais pas de SL qui remplace copy/fill sur les types natifs par les appels à memcpy/memset qui vont bien.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  11. #11
    Invité
    Invité(e)
    Par défaut
    Je viens de regarder, celle que j'utilise (STL Port 4.5, distribuée avec Borland Builder 6) a en fait une spécialisation des template fill et fill_n pour les types mono-octet (signed char, unsigned char et char), qui utilise memset.

    Francois

  12. #12
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Au temps pour moi alors.
    Et tu te retrouves quand même avec un truc plus gros ? Tu fais du fill sur des int, des choses comme ça ?
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  13. #13
    Invité
    Invité(e)
    Par défaut
    Oui, en fait, à un moment j'avais pris l'habitude d'écrire des

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fill_n(tab,tab+taille,0)
    ou des choses du genre pour initialiser des tableaux (généralement d'int, parfois d'unsigned short)

    L'exemple que je cite plus haut est extrème (mais bien réel malheureusement). Il s'agit d'un module de 150 lignes de C qui implémente un décodeur arithmétique (c'est à dire une série de fonctions qui lisent des données compactées par codage arithmétique).

    L'interface du module ressemblait donc à cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void decode_var(int nind,int *res,unsigned char *ptr)
    nind étant le nombre de données à décoder, res un tableau destiné à recevoir les données (pré-alloué), et ptr un pointeur du le début des données codées.

    Or, il y avait à la fin un gestionnaire de cas particulier qui, soit en cas d'erreur de lecture, soit pour une certaine valeur de l'entête des données d'entrée, renvoyait un tableau initialisé par une constante. Implémenté comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    else fill_n(res,nind,vdef);
    C'était le seul appel à la STL, avec donc un #include <algorithm> en haut du fichier...

    Cet appel (remplacé maintenant par un bête for(int i=0;i<nind;i++) res[i]=vdef se traduisait par un triplement de la taille de l'obj compilé (qui passait en mode optimisé, de 2 à 7k), rien de dramatique à l'échelle du programme, mais tout à fait exemplaire, je crois...

    Francois

  14. #14
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Ca serait très intéressant d'essayer sur un voir plusieurs autres compilo, car il est vrai que la STL fourni avec borland est assez exotique je crois.

  15. #15
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Autant je comprends que l'on ait du code bloat à utiliser std::fill au lieu de memset, en revanche je ne comprends pas que l'on en ait à utiliser std::fill au lieu d'une boucle for sur indices codée à la main.
    Cela sens le mauvais compilo -- maintenant BCB est un ancien ...
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  16. #16
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    Cela sens le mauvais compilo -- maintenant BCB est un ancien ...
    A mon avis, l'importance de l'augmentation constatée semble indiquer que BCB, quand il utilise la STL, inclut dans le code tout un tas de choses qui ne lui servent pas... (même mal optimisé un unique appel à fill_n ne peut générer plusieurs kilo-octets de code machine).

    Ceci est à rapprocher de l'"overhead iostream" dont on a parlé précédemment...

    En terme de vitesse, BCB fonctionne correctement. J'ai plusieurs fois essayé de le remplacer, en le comparant sur des programmes "calcul pur" avec GCC et Visual, et honnêtement, je n'ai jamais vu de différence spectaculaire. Il semblerait donc qu'ils ne soient pas aussi bien sur la taille...

    Si d'autres ont le temps de tester d'autres compilateurs sur des cas simples comme celui ci, je suis preneur...

    Sur le même thème, j'ai repéré une autre curiosité (que j'enjoins les utilisateurs d'autres compilateurs à tester...). J'ai quelque part un code qui ressemble à cela

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    int *Src=new int[nind];
    int *Res=new int[nind];
    vector<int> Val(nb);
    ...
    for(int i=0;i<nind;i++) {
            Res[i]=0;
            for(int j=0;j<nb;j++) if(Src[i]==Val[j]) {Res[i]=1;break;}
    }
    En gros, cela prend un tableau Src, et cela renvoie un tableau qui indique, pour chaque élément de Src, s'il appartient aux éléments du vecteur Val

    (je mets des tableaux pour isoler le comportement que je veux mettre en évidence...)

    J'observe, toujours sous Borland, que si j'utilise

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    int *Src=new int[nind];
    int *Res=new int[nind];
    vector<int> Val(nb);
    ...
    int *ptr=&Val[0];
    for(int i=0;i<nind;i++) {
            Res[i]=0;
            for(int j=0;j<nb;j++) if(Src[i]==ptr[j]) {Res[i]=1;break;}
    }
    Mon code tourne un peu (environ 15% en fait) plus vite...

    Je suis donc assez d'accord avec Luc, BCB 6 a presque 10 ans, il est donc assez vraisemblable que les optimisations nécessaires à l'utilisation intensive de la STL, des templates, et autres nouveautés relatives, y soit mal gérée...

    (maintenant, c'est aussi un outil très puissant quand on veut faire de l'interface... alors...)

    Goten, la STL est une STLPort, donc un truc assez mainstream, en fait... Je doute qu'elle soit en cause (surtout pour fill et fill_n qui sont peut être les trucs les plus bateaux qui soient...)

    Francois

  17. #17
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Citation Envoyé par fcharton Voir le message
    Sur le même thème, j'ai repéré une autre curiosité (que j'enjoins les utilisateurs d'autres compilateurs à tester...).
    J'en suis.
    On peux tester très précisément la pénalité imposée par les itérateurs par rapport aux pointeurs nus grâce au benchmark d'adobe.

    Il suffit de dézipper l'archive et de lancer le test contenu dans stepanov_vector.cpp. C'est une extension au fameux benchmarck de "pénalité d'abstraction" crée par Stepanov, le concepteur de la STL.

    Citation Envoyé par stepanov_vector.cpp
    Goal: examine any change in performance when moving from pointers to vector iterators

    Assumptions:
    1) Vector iterators should not perform worse than raw pointers.

    Programmers should never be tempted to write
    std::sort( &*vec.begin(), &*( vec.begin() + vec.size() ) )
    instead of
    std::sort( vec.begin(), vec.end() )

    HIstory:
    This is an extension to Alex Stepanov's original abstraction penalty benchmark
    to test the compiler vendor implementation of vector iterators.
    Mes résultats avec Visual Studio 10 beta 1 :
    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
     
    C
     
    test                            description   absolute   operations   ratio with
    number                                        time       per second   test0
     
     0                 "double pointer verify2"   3.77 sec   796.60 M     1.00
     1                 "double vector iterator"   3.81 sec   786.99 M     1.01
     2                 "double pointer reverse"   3.81 sec   786.78 M     1.01
     3         "double vector reverse_iterator"   3.83 sec   783.70 M     1.02
     4         "double vector iterator reverse"   3.81 sec   786.99 M     1.01
     5         "double pointer reverse reverse"   3.81 sec   786.78 M     1.01
     6 "double vector reverse_iterator reverse"   3.81 sec   786.99 M     1.01
     7 "double vector iterator reverse reverse"   3.81 sec   786.78 M     1.01
     
    Total absolute time for Vector accumulate: 30.47 sec
     
    Vector accumulate Penalty: 1.01
     
     
    test                                           description   absolute   operations   ratio with
    number                                                       time       per second   test0
     
     0                 "insertion_sort double pointer verify2"   1.44 sec    2.09 M     1.00
     1                 "insertion_sort double vector iterator"   1.44 sec    2.09 M     1.00
     2                 "insertion_sort double pointer reverse"   1.41 sec    2.13 M     0.98
     3         "insertion_sort double vector reverse_iterator"   1.41 sec    2.13 M     0.98
     4         "insertion_sort double vector iterator reverse"   1.42 sec    2.11 M     0.99
     5         "insertion_sort double pointer reverse reverse"   1.44 sec    2.09 M     1.00
     6 "insertion_sort double vector reverse_iterator reverse"   1.50 sec    2.00 M     1.04
     7 "insertion_sort double vector iterator reverse reverse"   1.49 sec    2.02 M     1.03
     
    Total absolute time for Vector Insertion Sort: 11.53 sec
     
    Vector Insertion Sort Penalty: 1.00
     
     
    test                                      description   absolute   operations   ratio with
    number                                                  time       per second   test0
     
     0                 "quicksort double pointer verify2"   2.16 sec   11.13 M     1.00
     1                 "quicksort double vector iterator"   2.23 sec   10.74 M     1.04
     2                 "quicksort double pointer reverse"   2.17 sec   11.05 M     1.01
     3         "quicksort double vector reverse_iterator"   2.16 sec   11.13 M     1.00
     4         "quicksort double vector iterator reverse"   2.17 sec   11.05 M     1.01
     5         "quicksort double pointer reverse reverse"   2.23 sec   10.74 M     1.04
     6 "quicksort double vector reverse_iterator reverse"   2.23 sec   10.74 M     1.04
     7 "quicksort double vector iterator reverse reverse"   2.23 sec   10.74 M     1.04
     
    Total absolute time for Vector Quicksort: 17.59 sec
     
    Vector Quicksort Penalty: 1.02
     
     
    test                                      description   absolute   operations   ratio with
    number                                                  time       per second   test0
     
     0                 "heap_sort double pointer verify2"   2.05 sec   11.72 M     1.00
     1                 "heap_sort double vector iterator"   2.20 sec   10.89 M     1.08
     2                 "heap_sort double pointer reverse"   2.73 sec    8.78 M     1.34
     3         "heap_sort double vector reverse_iterator"   2.81 sec    8.53 M     1.37
     4         "heap_sort double vector iterator reverse"   2.72 sec    8.83 M     1.33
     5         "heap_sort double pointer reverse reverse"   2.22 sec   10.82 M     1.08
     6 "heap_sort double vector reverse_iterator reverse"   2.22 sec   10.82 M     1.08
     7 "heap_sort double vector iterator reverse reverse"   2.22 sec   10.82 M     1.08
     
    Total absolute time for Vector Heap Sort: 19.17 sec
     
    Vector Heap Sort Penalty: 1.19
    Résutats:
    L'implémentation de Visual Studio est plutôt bonne sur ce point et réussi à supprimer quasiment toute trace d'overhead dans le passage pointeur nu/itérateur.

    Reste à examiner les résultats avec d'autres compilateurs, en particulier, avec BCB.

  18. #18
    Invité
    Invité(e)
    Par défaut
    Merci beaucoup Arzar!

    Je viens de faire le test sur borland 6, et c'est effectivement assez violent...

    Juste pour la comparaison pointeurs nus itérateurs (sans les reverse et tout le reste), je trouve (en optimisé) un écart de

    21% pour accumulate
    55% pour insertion_sort
    14% pour quick_sort
    21% pour heapsort

    Et quand on va vers des combinaisons plus complexes, ca tourne vite au massacre...

    J'ai également fait le test avec GCC+MingW32, et je trouve des performances correctes, mais pas aussi bonnes que la version de Visual que tu as postée...

    En gros, sous gcc il n'y a pas de penalité pour un itérateur normal, sauf sur quicksort (pénalité de 26% !), et on a des pénalités importantes (30 à 60%) pour des itérateurs inverses.

    J'essaierai de tester Borland 2007 et une version plus ancienne de Visual lundi... Ce qui me travaille, c'est que l'on peut apparemment avoir des problèmes même avec des compilateurs assez récents.

    Francois
    Dernière modification par Invité ; 18/07/2009 à 23h35.

  19. #19
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Quelle version de gcc? Faudra que je teste avec la 4.4
    Btw j'ai testé avec visual studio 2008 j'obtiens des résultats assez bizarre rien que pour l'accumulate sur un simple iterator :
    pointer : 3,58 secondes
    iterator : 40 secondes ...

    Et pareil pour tout les autres j'ai arrêter à accumulate d'ailleurs parce que bon... ça prenais trop de temps XD. Bon j'utilise pas du tout visual au quotidien alors je fais peut être quelque chose mal.... toujours est-il que je suis en release et l'optimisation en /02 ...
    Trop fatigué ce soir je verrais demain à tête reposé, mais il semble que j'obtienne les mêmes résultats sous VS2010 ...


    EDIT: ça me tracasse trop pour dormir donc voilà mes résultats sous VS2008 et en baissant int iterations à 150000 afin d'avoir des temps proche d'une seconde. (parce que 40 secondes c'est pas possible m ais je comprends quand même pas.) Les ratios reste les mêmes qu'avec 10 fois plus d'itérations :
    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
     
    c:\Documents and Settings\Goten\Mes documents\Visual Studio 2008\Projects\bench\
    Release\bench.exe
     
    test                            description   absolute   operations   ratio with
     
    number                                        time       per second   test0
     
     0                 "double pointer verify2"   0.34 sec   872.09 M     1.00
     1                 "double vector iterator"   4.23 sec   70.85 M     12.31
     2                 "double pointer reverse"   0.36 sec   833.33 M     1.05
     3         "double vector reverse_iterator"   4.88 sec   61.54 M     14.17
     4         "double vector iterator reverse"   4.89 sec   61.35 M     14.22
     5         "double pointer reverse reverse"   0.36 sec   833.33 M     1.05
     6 "double vector reverse_iterator reverse"   5.17 sec   58.02 M     15.03
     7 "double vector iterator reverse reverse"   5.09 sec   58.89 M     14.81
     
    Total absolute time for Vector accumulate: 25.33 sec
     
    Vector accumulate Penalty: 6.70
     
     
    test                                           description   absolute   operations   ratio
     with
    number                                                       time       per second   test0
     
     
     0                 "insertion_sort double pointer verify2"   0.19 sec    1.60 M     1.00
     1                 "insertion_sort double vector iterator"   2.34 sec    0.13 M     12.46
     2                 "insertion_sort double pointer reverse"   0.19 sec    1.60 M     1.00
     3         "insertion_sort double vector reverse_iterator"   3.61 sec    0.08 M     19.20
     4         "insertion_sort double vector iterator reverse"   3.59 sec    0.08 M     19.12
     5         "insertion_sort double pointer reverse reverse"   0.20 sec    1.48 M     1.08
     6 "insertion_sort double vector reverse_iterator reverse"   4.70 sec    0.06 M     25.02
     7 "insertion_sort double vector iterator reverse reverse"   4.72 sec    0.06 M     25.10
     
    Total absolute time for Vector Insertion Sort: 19.55 sec
     
    Vector Insertion Sort Penalty: 8.46
     
     
    test                                      description   absolute   operations   ratio with
     
    number                                                  time       per second   test0
     
     0                 "quicksort double pointer verify2"   0.20 sec   11.82 M     1.00
     1                 "quicksort double vector iterator"   0.63 sec    3.84 M     3.08
     2                 "quicksort double pointer reverse"   0.22 sec   10.96 M     1.08
     3         "quicksort double vector reverse_iterator"   0.83 sec    2.90 M     4.08
     4         "quicksort double vector iterator reverse"   0.83 sec    2.90 M     4.08
     5         "quicksort double pointer reverse reverse"   0.22 sec   10.96 M     1.08
     6 "quicksort double vector reverse_iterator reverse"   1.05 sec    2.29 M     5.16
     7 "quicksort double vector iterator reverse reverse"   1.06 sec    2.26 M     5.23
     
    Total absolute time for Vector Quicksort: 5.03 sec
     
    Vector Quicksort Penalty: 2.87
     
     
    test                                      description   absolute   operations   ratio with
     
    number                                                  time       per second   test0
     
     0                 "heap_sort double pointer verify2"   0.20 sec   11.82 M     1.00
     1                 "heap_sort double vector iterator"   0.89 sec    2.69 M     4.39
     2                 "heap_sort double pointer reverse"   0.25 sec    9.60 M     1.23
     3         "heap_sort double vector reverse_iterator"   1.28 sec    1.87 M     6.31
     4         "heap_sort double vector iterator reverse"   1.25 sec    1.92 M     6.16
     5         "heap_sort double pointer reverse reverse"   0.22 sec   10.96 M     1.08
     6 "heap_sort double vector reverse_iterator reverse"   1.56 sec    1.54 M     7.70
     7 "heap_sort double vector iterator reverse reverse"   1.55 sec    1.55 M     7.62
     
    Total absolute time for Vector Heap Sort: 7.20 sec
     
    Vector Heap Sort Penalty: 3.88

  20. #20
    Invité
    Invité(e)
    Par défaut
    gcc 3.4.5, je crois.

    Pour Visual, il doit y avoir un paramètre de compilation qui pose pb (t'es sur que tu es en release? ou que tu n'utilises pas une version "debug" de la stl?) Parce qu'un rapport de 1 à 12 pour une opération comme accumulate (qui se contente d'incrémenter et de déréférencer), ca parait gros, quand même...

    Francois

Discussions similaires

  1. Réponses: 2
    Dernier message: 25/06/2014, 11h45
  2. Code sujet à l'endianness ?
    Par apesle dans le forum C
    Réponses: 5
    Dernier message: 11/05/2008, 17h19
  3. Petite question au sujet du code Hamming
    Par sylsau dans le forum Algorithmes et structures de données
    Réponses: 5
    Dernier message: 28/02/2006, 12h30

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