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 :

Le coût d'un pointeur


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut Le coût d'un pointeur
    Voici une ébauche de code qui trie un vector, puis un autre vector sur des références des éléments du premier.
    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
    struct IdStr
    {
    	unsigned id;
    	std::string str;
    	friend bool operator<(IdStr const & l, IdStr const & r) noexcept
    	{
    		int cmp = (l.id - r.id);
    		return ((cmp == 0) ? (l.str < r.str) : (cmp < 0));
    	}
    };
    void main()
    {
    	std::vector<IdStr> is;
    	// remplir le vector is ...
     
    	std::sort(is.begin(), is.end());
     
     
    	std::vector<std::reference_wrapper<IdStr>> ris;
     
    	// re-remplir le vector is ...
    	ris.assign(is.begin(), is.end());
     
    	std::sort(ris.begin(), ris.end());
    }
    Assez curieusement le tri des références est plus lent de l'ordre d'un bon 15%. J'aurais cru qu'il fasse au moins aussi bien puisque lors du tri les éléments déplacés ne sont jamais que des pointeurs et non pas des instances de structure (qui contient quand même un std::string dans mon exemple).
    En bref, le coût CPU supplémentaire se trouve dans l'appel à la fonction de comparaison (rigoureusement la même dans les deux tris) qui pourtant ne fait qu'une indirection via le pointeur encapsulé dans la référence. Et je suis surpris que la différence soit aussi marquée.
    Merci pour vos remarques.

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 151
    Billets dans le blog
    4
    Par défaut
    Hello,

    cela ne me surprend pas, le reference_wrapper est un pointeur camouflé, donc l'indirection risque aussi de dire remise en cache. Concrètement tu perds probablement une bonne partie de l'intérêt du vector et sa contiguïté des données.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    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,

    De plus, il faut savoir que le simple fait de vouloir trier un ensemble qui est déjà trié (ou presque) te place "forcément" dans le pire des cas possible.

    Quelle que soit la complexité de ton algorithme de tri, cela se passera comme lors du remplicage d'un arbre binaire: si les données sont fournies dans un ordre déjà trié, tu observera beaucoup plus de rotations dans tous les sens que si tu décidait de fournir les mêmes données dans un ordre dans lequel aucune rotation ne devait se produire (par exemple, dans l'ordre 8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13,15)

    Si is est déjà trié lorsque tu essayes de trier ris, tu ne dois pas t'étonner si ton algorithme de tri "travaille" plus longtemps pour trier ris, car tu sera forcément dans "le pire des cas" possible pour ton algorithme.

    Peut-être t'y es tu pris autrement pour évaluer les performances, mais, si tu l'as fait avec le code que tu présentes ici, le résultat n'a pas grand chose d'étonnant à cause de ce "pire des cas"
    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

  4. #4
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Euh, non koala. J'ai bien sûr testé avec une disposition quelconque des éléments à chaque fois, voir mon commentaire "re-remplir le vector is" dans le pseudo-code fourni juste avant de travaller avec ris.
    J'ai aussi testé avec un autre algorithme inspiré des "tris à clé " (un mix de "count sort" et "MSD radix sort") pour lequel il n'y a pas en théorie de "pire des cas" comme tu le dis
    On est en complexité constante O(d(k+n)) (d et k étant des constantes indépendantes de n, avec d << k << n).

    Bousk, je me suis souvent demandé comment programmer en tenant compte des optimizations possibles des processeurs quand on manipule des millions de données... Dans mes essais, peu importe le nombre de données, le constat est le même.

    Merci

  5. #5
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    La mémoire cache joue toujours un rôle, je pressens que les 15% seraient dus à des fautes de page. Et dans ce cas l'écart devrait diminuer pour de petits tableaux de l'ordre de centaines d'éléments.
    Le mécanisme de cache gère bien des données lues successivement dans une zone contiguë. Les accès aléatoires sont par contre une plaie.
    cas I. On a un vecteur de données relativement petites (cache favorisé si moins d'une ligne de cache par donnée soit 64 octets) qui pointent sur des chaînes dynamiques (cache perturbé).
    cas II. On a un vecteur de pointeurs (cache favorisé) qui pointent sur des données (cache perturbé) qui pointent sur des chaînes dynamiques (cache perturbé).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Cercle bleu à coté du pointeur
    Par vinson2008 dans le forum Windows Vista
    Réponses: 2
    Dernier message: 07/04/2012, 10h32
  2. [Concept] Curseur coté client et curseur coté serveur
    Par freud dans le forum Décisions SGBD
    Réponses: 2
    Dernier message: 13/09/2002, 22h13
  3. djgpp et pointeurs far -2
    Par elvivo dans le forum Autres éditeurs
    Réponses: 16
    Dernier message: 29/07/2002, 22h43
  4. djgpp et pointeurs far
    Par elvivo dans le forum C
    Réponses: 2
    Dernier message: 13/07/2002, 00h44
  5. [Choix] SGDB pour Entreprise : coût, efficacité, etc.
    Par grassat dans le forum Décisions SGBD
    Réponses: 4
    Dernier message: 15/06/2002, 08h52

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