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

Contribuez C++ Discussion :

De la rapidité du code [Trucs & Astuces]


Sujet :

Contribuez C++

  1. #141
    Membre averti Avatar de Rafy
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    415
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 415
    Points : 417
    Points
    417
    Par défaut
    C'est vrai que les compilo sont maintenant très très évolués.... Même entre 2 générations proches visual studio 2005 et son prédécesseur. Il y a des différences ! (surtout quand on demande une taille pour l'exe la plus petite possible.)
    Première grosse démo en construction :
    http://bitbucket.org/rafy/exo2/

  2. #142
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Points : 460
    Points
    460
    Par défaut
    Et bien, mon compilo ne fait pas de telles optimisations automatiquement. Et c'est pas faute d'avoir essayer.
    Mon compilo (Intel C++ compiler sous Windows) est pourtant de loin le meilleur que j'ai trouvé. Mais peut-être que sur ce point précis d'autres compilos feront mieux, mais j'en doute.

    Si ça vous intéresse, je veux bien vous montrer le code assembleur généré en mélangeant SSE et mon développement de boucles.

  3. #143
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    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 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Citation Envoyé par Charlemagne
    Et ton BUFFER_SIZE il vient d'où? J'y peux rien si les registres SSE ont une taille fixe de 16 octets.
    Je veux bien faire toutes les constantes que vous voulez, mais cessez de ne parler que de cette constante alors que j'illustrais mon propos sur l'optimisation SSE par un exemple de 2 lignes.
    Oui, je ne parlais que des constantes magiques qui n'ont aucun impact sur les perfs, juste la maitenabilité & cie.


    (Dans les autres techniques de compil' pour une meilleure utilisation du pipeline, tu as le duff-device aussi -- pour ceux qui veulent s'amuser à faire des comparaisons, tout ç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...

  4. #144
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 26
    Points : 22
    Points
    22
    Par défaut
    Bonjour a tous, je fais du c++ depuis 6 mois, j'ai quelques questions concernant la rapidité du code ( certains points ont déjas étés évoquées, mais les personnes se sont contredites ... ).

    Donc selon vous, est ce que ces différentes étapes permettent - ou non - d'augmenter la rapidité du code "dans l'étape finale" ( le plus efficace étant de bien construire les fonctions, et de ne pas faire compliqué ce que l'on peut faire simplement, je vous l'accorde ), et pourquoi ( justifiez un minimum si ca ne vous embête pas trop ? :

    - utiliser "const" pour toutes les variables qui ne changeront pas.
    - remplacer les int<65000 et quelques ( 4 octets ) par des short ( 2 octet ).
    - utiliser les passage par référence au lieu des passages par valeures ( il me semble qu'il n'y a pas de copie de variable dnas ce cas la )
    - éviter d'inbriquer les fonctions les unes dans les autres ( c'est le conflit rapidité/lisibilité ).
    - et enfin, utiliser des additions au lieu de multiplications. Apparament, une multiplication est plus longue qu'une addition. On peut donc supposer que 2*A est plus long a faire que A+A, A+A+A plus rapide que 3*A ( on "peut supposer" ). Ce raisonnement est il valable, et si oui, jusqu'a ou ?

  5. #145
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par dekron
    - utiliser "const" pour toutes les variables qui ne changeront pas.
    Là, ça dépend du compilo. C'est généralement plus important pour les pointeurs/références.
    - remplacer les int<65000 et quelques ( 4 octets ) par des short ( 2 octet ).
    Là, j'ai entendu des avis contradictoires: Il parait que les architectures modernes travaillent mieux sous leur type "natif", le reste prenant au contraire du temps supplémentaire (extension de signe, etc).
    - utiliser les passage par référence au lieu des passages par valeures ( il me semble qu'il n'y a pas de copie de variable dnas ce cas la )
    Pour les gros types uniquement, bien sûr. Ne passe pas un entier par référence.
    Et surtout, n'oublie jamais const là où il est valable, sinon on ne s'en sort plus.
    - éviter d'inbriquer les fonctions les unes dans les autres ( c'est le conflit rapidité/lisibilité ).
    C'est à cela que sert de déclarer une fonction static inline : S'il elle n'est appelée qu'une seule (ou peu de) fois, et seulement dans le fichier source qui la contient, elle sera directement collée dans le code au lieu d'être appelée.
    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.

  6. #146
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 26
    Points : 22
    Points
    22
    Par défaut
    inline sert effectivement a écrire la fonction directement dans le code, pour éviter qu'elle soit appelée. Ce mot clef sert donc principalement pour les petites fonctiosn qui sont tres souvent utilisées non ?

    quand je parlais des fonctions les unes dans les autres, je parlais des fonction récursives ( javais oublié le mot ).

    Si je prends l'exemple d'un switch a 50 cases ( tooutes fonctionnent sur le meme principe, seule les données modifiées changent ), dont 5 de ces cases sont des fonctions qui sont utilisées dans les 45 autres ( mais la récursion s'arrête la ).

    Cela est fait pour éviter de tout le temps faire du recopiage, améliorer la lisibilité.
    Au contraire, on pourrait les recopier a chaque fois, voir a l'extreme, faire une fonction pour chaque "case" ... mais bon on perd la notio nde fonction, et ce serait ne pas utiliser les outils qui s'offrent a nous, c'est pas tres malin.

    Le probleme est que d'appeler la 50eme case, puis encore faire appel a la fonction doit prendre pas mal de temps.

  7. #147
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    inline ne sert à rien, c'est un mot-clé qui dit au compil qu'il peut, s'il veut, inliner, mais c'est tout.
    Pour les int vs short, si on en fait plusieurs en même temps, des short peuvent être rentable si on a des instructions parallèles, sinon, non.
    Si tu as un switch à 50 cas, change ton code, ça vaudra mieux.
    Spécifier un variable comme étant const ne va pas permettre au compilateur d'optimiser beaucoup plus. Pourquoi ? Parce que même si un objet est déclaré const, il peut ne pas être constant -> mutable, donc il ne peut rien faire. En revanche, c'est excellent pour le programmeur qui peut optimiser certains cas en surchargeant une fonction.

  8. #148
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Points : 460
    Points
    460
    Par défaut
    Je confirme ce que disent Miles et Médinoc.
    Je trouve néanmoins les propositions de Dekron négligeable pour l'optimisation (et très incertaines) sauf celle du passage par référence.

    Je ne vois effectivement pas comment les compilos pourraient tirer profit du mot réservé "const" pour optimiser la vitesse. "const" est quand même beaucoup trop pratique pour que je puisse dorénavant m'en passer (principalement sur les références).

    Je vois néanmoins un genre d'occasion où "const" peut permettre d'optimiser les calculs: sur les fonctions membres optimisées. Par exemple la spécialisation de vector<bool>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    template<class A>
    class vector<bool,A>
    {
      typedef pseudo_bool<...> reference;
      typedef bool const_reference;
      reference       operator[](size_type i)       {...}
      const_reference operator[](size_type i) const {...}
    };
    donc un "const vector<bool>" sera plus rapide qu'un "vector<bool>"

  9. #149
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Tout à fait d'accord, dans certains cas, dans une fonction const, on peut enlever quelques traitements inutiles !

  10. #150
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    26
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 26
    Points : 22
    Points
    22
    Par défaut
    Citation Envoyé par Charlemagne
    Je trouve néanmoins les propositions de Dekron négligeable pour l'optimisation (et très incertaines) sauf celle du passage par référence.
    hum ... c'était des questions et pas des propositions ^^

    Pouvez vous m'expliquer en détail, en quoi le "const", dans le cas d'un pasage par référence, est "pratique" ou offre un "gain de performances" ( pour moi, déclarer const uen variable, c'est juste pour que le compilo dise non si on lui affecte une autre valeur non ? )

  11. #151
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    un const & permet de passer juste une référence et empêche la fonction de modifier ce qui n'est pas mutable.

  12. #152
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Points : 460
    Points
    460
    Par défaut
    hum ... c'était des questions et pas des propositions ^^
    'tschuldigung

    Pouvez vous m'expliquer en détail, en quoi le "const", dans le cas d'un pasage par référence, est "pratique" ou offre un "gain de performances" ( pour moi, déclarer const uen variable, c'est juste pour que le compilo dise non si on lui affecte une autre valeur non ? )
    Justement, ce n'est (a priori) dans l'immense majorité des cas pas plus rapide si la référence est constante. Sauf par exemple dans un cas d'un passage d'un vector<bool>.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template<class T,class A> void f(const vector<T,A> &X) {...}
    La référence constante assure à l'utilisateur que la variable ne sera pas (à moins d'un cast) modifiée à l'intérieur même de la fonction, tout en permettant un passage rapide (sans copie).

  13. #153
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    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 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Cela permet aussi d'accepter les temporaires non nommés.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // code qui ne compilera pas.
    f(std::string & t) { std::cout << t; }
    int main() {
        f("toto"); // KO 
         //  pas de conversion implicite possible de const char* à string&
     
        std::string toto = "toto";
        f(toto); // OK
        const std::string titi= "titi";
        f(titi); // KO; titi est non modifiable
     
        f(toto+"toto"); // KO : le résultat de toto+"toto" est une chaine temporaire non nommée
    }
    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...

  14. #154
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Points : 460
    Points
    460
    Par défaut
    Cela permet aussi d'accepter les temporaires non nommés.
    J'ai l'impression que c'est pas entièrement vrai. C'est effectivement ce que fait GCC. Mais j'ai vu des différences notables entre compilos (VC x, GCC, Intel Compiler) . Je suis toutefois incapable d'en décrire tous les détails.
    Le comportement de GCC paraît sensé à première vue mais ça m'a joué des tours.

    Voici un exemple inspiré d'un de mes cas.
    Une fonction 'sub' qui retourne la partie d'un vecteur (en fait une classe proxy SubVector) et une fonction 'f' qui modifie le contenu d'un vecteur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    template<class Vect> SubVector<Vect> sub(Vect&X, int i, int n) {...}
    template<class Vect> void f(Vect &X) { X[0]=0; }
    Et bien l'appel 'f(sub(X,2,5))' ne marche pas avec GCC, mais aucun problème avec ICL. Pour faire plaisir à GCC il faut effectivement supprimer les temporaires
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SubVector<mon_vecteur> subX=sub(X,2,5);
    f(subX)
    Enfin tout ça c'est hors sujet, c'est pas de l'optimisation...

  15. #155
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    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 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Pour clore l'HS.
    Alors le comportement d'ICL n'est pas conforme. Beaucoup de vieux compilateurs procédaient également de la sorte.

    Ici, ce que tu peux faire, c'est prendre ton objet par copie. Si ce n'est qu'un proxy qui agit comme une vue sur autre chose, ce ne doit pas être un problème, j'imagine que l'objet ne contient qu'un pointeur et une taille, ce qui est tout petit. (ou comment faire semblant de revenir dans le sujet)

    Et pour la constance, il n'est pas rare que l'on finisse avec un proxy et un const_proxy dans ces cas là. (C'est la même chose qu'avec les itérateurs)
    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. #156
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Points : 460
    Points
    460
    Par défaut
    Alors le comportement d'ICL n'est pas conforme. Beaucoup de vieux compilateurs procédaient également de la sorte.
    Peut-être bien, ou bien plus probablement ICL copie le comportement de VCx qui sont (VC8?) loin d'être conformes.
    Ici, ce que tu peux faire, c'est prendre ton objet par copie. Si ce n'est qu'un proxy qui agit comme une vue sur autre chose, ce ne doit pas être un problème, j'imagine que l'objet ne contient qu'un pointeur et une taille, ce qui est tout petit. (ou comment faire semblant de revenir dans le sujet)
    En fait dans mon exemple, la classe proxy contiendrait plutôt une référence sur le vecteur, mais c'est pas le propos: elle serait ici effectivement petite.
    Cette solution est néanmoins à exlure, car j'ai des quantités de classes proxy (certaines petites en mémoire, d'autres grandes), je veux avoir une seule fonction template par calcul et éviter de faire trop de cas particuliers.

    Et donc, que le compilo considère un temporaire comme constant reste une contrainte, même si dans 99% des cas c'est justifié.

  17. #157
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Un temporaire constant, c'est pratique pour que les gens comprennent bien que ce n'est qu'un temporaire et que le modifier ne sert à rien

  18. #158
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Points : 460
    Points
    460
    Par défaut
    un temporaire constant c'est bien dans la majorité des cas, mais dans le cas de proxis c'est ch..., ça oblige à faire une variable locale temporaire.
    Mon exemple revient à dire (en le carricaturant à peine) que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Variable X;
    {
      Proxi PX=g(X);
      f(PX);
    }
    n'est pas (toujours) équivalent pour un compilo à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Variable X;
    f(g(X));

  19. #159
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Effectivement, dans ce cas-ci, c'est embêtant.

  20. #160
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    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 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Un proxy n'étant généralement qu'un intermédiaire vers la véritable donnée, je ne crois pas en avoir manipulé des qui soient lourds.
    Sinon, j'avoue que j'ai de moins en moins de temporaires non nommées. J'ai aujourd'hui tendance à déclarer des données temporaires nommées non modifiables. La faute à des core qu'il me faut parfois analyser.
    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...

Discussions similaires

  1. Réponses: 1
    Dernier message: 31/08/2014, 17h52
  2. Optimiser rapidité code
    Par bobosh dans le forum VBA Access
    Réponses: 2
    Dernier message: 28/08/2008, 16h12
  3. Optimisation code pour gagner en rapidité
    Par polodu84 dans le forum MATLAB
    Réponses: 2
    Dernier message: 05/03/2008, 15h32
  4. requete QBE / requete code : rapidité et index
    Par LostIN dans le forum Requêtes et SQL.
    Réponses: 11
    Dernier message: 05/07/2006, 08h54
  5. [rapidité du code] Mise a jour a partir d'un TQuery.
    Par goethe dans le forum Bases de données
    Réponses: 4
    Dernier message: 27/10/2004, 09h01

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