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

Téléchargez C++ Discussion :

[À télécharger] [Programmation générique] Classe trait pour le type de passage d'argument


Sujet :

Téléchargez C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut [À télécharger] [Programmation générique] Classe trait pour le type de passage d'argument
    Bonjour, Je vous propore un nouvel élément à utiliser : [Programmation générique] Classe trait pour le type de passage d'argument



    Cette fonction permet de choisir automatiquement le meilleur moyen pour le passage d'argument. Elle est tirée de l'article d'Alp Mestan sur les classes de traits et de politiques.



    Qu'en pensez-vous ?

  2. #2
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    Juste une question, y a t-il un avantage (d'un point de vue performance) lorsqu'il s'agit d'un int de le passer par copie plutôt que par référence constante ? N'est-ce pas la même taille ?

  3. #3
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Citation Envoyé par NoIdea Voir le message
    Juste une question, y a t-il un avantage (d'un point de vue performance) lorsqu'il s'agit d'un int de le passer par copie plutôt que par référence constante ? N'est-ce pas la même taille ?
    Les références et les pointeurs ont une taille hardware égale à la taille du mot natif. La taille d'un int est décorélée de la taille de mot native. Donc non, ce n'est pas toujours la même taille (en particulier en 64 bits, ou la taille d'une référence est 64 bits tandis que l'int est resté à 32 bits sur la plupart des plateformes).

    Ceci dit, passer un int en référence constante (ou toute autre donnée dont la taille est égale ou inférieure à celle du mot natif) n'a pas vraiment de sens. En termes de performance, le gain (s'il y a, et j'en doute) est négligeable.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  4. #4
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    Si je comprend bien, tu dis que cette classe de politique est uniquement didactique et n'est pas utilisée dans un cas réel ?

  5. #5
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Non, il a juste dit que la taille d'un int n'est pas lié à la taille "natif" du système contrairement à celle d'un pointeur (d'un référence). Et que, pour les int mais aussi pour d'autre type, si la taille est inférieure à celle d'un pointeur le passage par référence ne serait pas nécessairement un gain. Et c'est exactement ce choix que permet de faire cet outil.

    Ne serait-il pas mieux de comparer sizeof(T) avec sizeof(void*) plutôt que 8 ?

  6. #6
    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
    Citation Envoyé par NoIdea Voir le message
    Si je comprend bien, tu dis que cette classe de politique est uniquement didactique et n'est pas utilisée dans un cas réel ?

    Bien sur que si, regarde boost::call_traits

  7. #7
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    Non, il a juste dit que la taille d'un int n'est pas lié à la taille "natif" du système contrairement à celle d'un pointeur (d'un référence).
    Il me semblait pourtant que les processeurs 64 bits préféraient les int de taille 64. En tout cas, pour les char, c'est évident.

    Et que, pour les int mais aussi pour d'autre type, si la taille est inférieure à celle d'un pointeur le passage par référence ne serait pas nécessairement un gain.
    Cela je l'avais compris car toute référence est pointeur caché. Cependant, bien que ce ne soit pas "nécessairement un gain", il se peut que cela ne change rien du tout. De plus, même si le pointeur à pour taille 8 octets et le int 4 octets, le gain en performance est négligeable d'après ce que j'ai compris de ceci :

    En termes de performance, le gain (s'il y a, et j'en doute) est négligeable.
    A moins que tu veuilles dire que c'est la référence constante qui n'apporte aucun gain.

    Ne serait-il pas mieux de comparer sizeof(T) avec sizeof(void*) plutôt que 8 ?
    Cela me paraitrait plus cohérent.

    Donc, je redemande, dans le cas de la copie, on peut gagner jusqu'à 7 octets sur les processeurs habituels. Est-ce que cela change quelque chose au performances ?
    Le compilateur n'est-il pas déjà capable d'effectuer ce genre d'optimisation ?
    N'est-ce pas alourdir le temps de compilation pour pas grand chose ?
    Est-ce que la copie permet au compilateur de mieux optimiser (ce qui me semble être la raison qui justifie le plus ce type de politique) ?

    Bien sur, je ne dis pas que cette classe désavantage un programme, je dis juste qu'il me semble qu'elle n'apporte pas de gain majeur. Ais-je tord ?

    Bien sur que si, regarde boost::call_traits
    Je vais regarder voir s'il donne la raison pour laquelle il faut l'utiliser.



    Concernant, toutes ces histoires de copies et de passage par référence, peut-il y avoir un gain en déclarant la variable globale (pas de copie je crois) ? Bien sur, ce serait une optimisation du compilateur pas de moi (et je n'ai aucune idée de comment marche les variables globales).

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 301
    Par défaut
    ne faudrait-il pas en plus vérifier que le type est copie-constructible et sinon le passer par référence constante?

  9. #9
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Citation Envoyé par NoIdea Voir le message
    Si je comprend bien, tu dis que cette classe de politique est uniquement didactique et n'est pas utilisée dans un cas réel ?
    Non, elle a une réelle utilité.

    Par exemple, on aurait pu réécrire std::vector<X>::push_back() ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    template <class T>
    class vector
    {
    public:
      // il faudrait ajouter ConstParamType sur le modèle de ParamType
      void push_back(typename Calltraits<T>::ConstParamType value)
      {
        ...
      }
    };
    (pour info, je rappelle que le prototype donnée par C++98 est push_back(T); même pas push_back(T& const)).

    T n'est pas toujours un type de base ; ça peut être absolument n'importe quoi.

    Citation Envoyé par NoIdea Voir le message
    Il me semblait pourtant que les processeurs 64 bits préféraient les int de taille 64. En tout cas, pour les char, c'est évident.
    Plus exactement, ils font ce qu'ils veulent. Mais il y a tellement de code écrit qui définissent "typedef unsigned int uint32" que les vendeurs de compilateurs ont bien souvent décidé de laisser les int sur 32 bits. les long font généralement 64 bits (sur une architecture 64 bits, s'entend).

    Citation Envoyé par NoIdea Voir le message
    Cela je l'avais compris car toute référence est pointeur caché. Cependant, bien que ce ne soit pas "nécessairement un gain", il se peut que cela ne change rien du tout. De plus, même si le pointeur à pour taille 8 octets et le int 4 octets, le gain en performance est négligeable d'après ce que j'ai compris de ceci :
    Il peut y avoir un gain infinitésimal, parce que le microprocesseur est optimisé pour lire des mots de 64 bits (en 64 bits, toujours). Du coup, lire un entier de 32 bits lui demande plus d'opérations microcodées. Ceci-dit, on parle de ce qui se passe dans le microcode, donc d'une fraction de l'horloge externe du microprocesseur. Il y a peu de chance pour que ça ait une répercussion à l'extérieur de celui-ci.

    Citation Envoyé par NoIdea Voir le message
    A moins que tu veuilles dire que c'est la référence constante qui n'apporte aucun gain.
    C'est ce que j'ai dit

    Citation Envoyé par NoIdea Voir le message
    Donc, je redemande, dans le cas de la copie, on peut gagner jusqu'à 7 octets sur les processeurs habituels. Est-ce que cela change quelque chose au performances ?
    Même réponse.

    Citation Envoyé par NoIdea Voir le message
    Le compilateur n'est-il pas déjà capable d'effectuer ce genre d'optimisation ?
    N'est-ce pas alourdir le temps de compilation pour pas grand chose ?
    Non, hélas. Le compilateur a l'obligation de faire ce qu'on lui dit de faire. Il a peu de latitude pour modifier le code (il ne peut le faire que si le code modifié se comporte exactement comme l'original).

    Citation Envoyé par NoIdea Voir le message
    Est-ce que la copie permet au compilateur de mieux optimiser (ce qui me semble être la raison qui justifie le plus ce type de politique) ?
    C'est un débat intéressant : le compilateur peut faire des élisions de code en cas de copie d'objets lourds, notamment s'ils ne sont pas modifiés. Sur le code suivant, un compilateur intelligent n'appellera le constructeur de la classe que s'il lui fait initialiser le paramètre à partir d'une valeur qui n'est pas du type du paramètre :

    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
    template <class T>
    T identify(T t)
    { return t; }
     
    struct X
    {
    ... (beaucoup de données)
      void do() { ... }
    };
     
    int main()
    {
      X x;
      identity(x).do(); // aucune copie, grâce aux 
                          // différentes optimisations du compilateur.
    }
    Le problème est que ce comportement n'est pas défini par le standard (ne pas comprendre que le standard le rend indéfini ; juste qu'il n'en parle pas, et du coup, bien que n'étant pas contraire au standard, il n'est pas obligatoire pour un vendeur de compilateur de l'implémenter).

    Citation Envoyé par NoIdea Voir le message
    Bien sur, je ne dis pas que cette classe désavantage un programme, je dis juste qu'il me semble qu'elle n'apporte pas de gain majeur. Ais-je tord ?
    Oui, parce qu'on parle de tous les types imaginables, pas seulement les types de base.

    Citation Envoyé par NoIdea Voir le message
    Je vais regarder voir s'il donne la raison pour laquelle il faut l'utiliser.
    Ne t'inquiète pas, de telles raisons existent

    Citation Envoyé par NoIdea Voir le message
    Concernant, toutes ces histoires de copies et de passage par référence, peut-il y avoir un gain en déclarant la variable globale (pas de copie je crois) ? Bien sur, ce serait une optimisation du compilateur pas de moi (et je n'ai aucune idée de comment marche les variables globales).
    Si tu souhaites passer par des variables globales, tu te trouves dans un autre problème : n'importe qui peut les modifier et tu sacrifie la réentrance (pas possible d'écrire une fonction récursive, pas possible d'écrire une fonction appelable depuis plusieurs threads,...).
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  10. #10
    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
    Le problème est que ce comportement n'est pas défini par le standard (ne pas comprendre que le standard le rend indéfini ; juste qu'il n'en parle pas, et du coup, bien que n'étant pas contraire au standard, il n'est pas obligatoire pour un vendeur de compilateur de l'implémenter).
    Tu veux rire? La copy-elision est définie par le standard hein!

  11. #11
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Citation Envoyé par Goten Voir le message
    Tu veux rire? La copy-elision est définie par le standard hein!
    Effectivement. Mea culpa. Et pour référence, parce que j'ai eu du mal à trouver : C++98, 12.8 [class.copy] §15.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  12. #12
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    Non, hélas. Le compilateur a l'obligation de faire ce qu'on lui dit de faire. Il a peu de latitude pour modifier le code (il ne peut le faire que si le code modifié se comporte exactement comme l'original).
    Mais ce serait le cas non ?


    Oui, parce qu'on parle de tous les types imaginables, pas seulement les types de base.
    Mais presque tout sizeof(classe ou structure créée par l'utilisateur) > sizeof(void*) ?

    De plus,
    ne faudrait-il pas en plus vérifier que le type est copie-constructible et sinon le passer par référence constante?
    Ne t'inquiète pas, de telles raisons existent
    Je me répète, mais dans le meilleur des cas, sa ne faits gagner que 7 octets ? n'est-ce pas un gain ridicule dans la plupart des cas ?

    Si tu souhaites passer par des variables globales, tu te trouves dans un autre problème : n'importe qui peut les modifier et tu sacrifie la réentrance (pas possible d'écrire une fonction récursive, pas possible d'écrire une fonction appelable depuis plusieurs threads,...).
    Ce n'est pas moi qui le souhaite, ce serait une potentielle optimisation du compilateur. A t-il le droit de faire cela ?


    Dernières questions :

    -Quand ne faut-il pas utiliser cette classe pour le passage par référence par conséquent ?

    -Cette classe peut-elle avoir un impacte significatif sur le temps de compilation si elle est utilisée partout ?

Discussions similaires

  1. Réponses: 3
    Dernier message: 22/04/2013, 12h07
  2. Traits pour classes définissant un typedef
    Par Florian Goo dans le forum Langage
    Réponses: 11
    Dernier message: 03/06/2009, 18h09
  3. Types génériques: Class is a raw type
    Par lexsteens dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 22/03/2008, 04h40
  4. Réponses: 12
    Dernier message: 23/09/2006, 12h12

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