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 :

Différence de performances entre entiers signés et non signés


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    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 Différence de performances entre entiers signés et non signés
    Salut à tous,


    je me trouve face à un cas optimisé par le compilateur que je m'explique pas, enfin je m'explique pas la différence plus que notable de performances engendrés voici le code (tout ce qu'il y'a de plus banal) :

    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
     
    #include <iostream>
     
    int main()
    {
         int maxLenght = 0, result = 0, node, chainLenght;
     
        for(unsigned int i = 1; i<1000000; ++i)
        {
     
            node = i;
     
            chainLenght = 0;
     
            while(node!=1)
            {
                if(node%2 == 0)
                {
                    node = node/2;
                }
                else //node is odd
                {
                    node = 3*node + 1;
                }
     
                ++chainLenght;
            }
     
            if(chainLenght > maxLenght)
            {
                maxLenght = chainLenght;
                result = i;
            }
        }
     
        std::cout << result;
        return 0;
    }
    Je compile ce code puis j'exécute je m'attendais à quelque chose d'assez lent ... j'ai été servi : 15 minutes plus tard j'avais toujours aucun résultat, j'ai donc stoppé et cherché si il y'avait pas de boucle infinie ou autre. Puis me rendant à l'évidence me suis dit autant gagné un peu sur les types et les passé en unsigned int étant sur de n'avoir aucunes valeurs négatives :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
         unsigned int maxLenght = 0, result = 0, node, chainLenght;
    Je recompile, exécute et là, en moins d'une seconde j'ai un résultat (valide soit dit en passant).

    15 min vs 1 seconde... je trouve cette différence énorme, donc j'aimerais savoir si c'est parce que en signé il y'a des mécanismes de vérification qui se font dans mon dos? Ou alors le compilo a vraiment vraiment bien optimisé avec les unsigned.


    Pour info j'ai compilé sous mingw en release et avec l'option -O3.

    Merci d'avance pour vos réponses.

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Tient, cela ressemble à une suite de syracuse !!

    Une petite idée comme cela, mais il faudrait voir le code assembleur généré. Ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
                if(node%2 == 0)
                {
                    node = node/2;
                }
    Quand node est unsigned,
    • l'opération modulo 2 peut être remplacée par un test sur le bit de poid faible (ce qui n'est peut être pas vrai en logique signée, à confirmer). Je ne sais pas en quoi est transformé le modulo en assembleur (une division puis test du reste, cela doit être assez long)
    • la division par 2 peut être remplacée par un décalage (ce qui n'est peut être pas vrai en logique signée)
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    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
    Yep ça en est bien une.


    Bon euh là j'ai fait ça vite fait sous windows et code::blocks, donc je sais pas comment avoir accès à l'assembleur généré :/. (si quelqu'un a une idée), sinon je ferais ça demain sous linux avec gcc.

  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,

    Ce serait bien possible que l'optimisation puisse se faire en logique signée et non signée car, sauf erreur, les processeurs "PC" travaillent en complement à 2 lorsqu'ils utilisent des nombres signés (et négatifs)

    L'"astuce", c'est que tu ne devrais normalement pas avoir de nombres négatifs dans une suite de syracuse (sauf en cas de dépassement de valeur)

    Pour obtenir le code assembleur, il faut passer par la compilation en mode console (menu démarrer->exécuter->taper cmd) et lancer la commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gcc -S fichier_a_compiler.cpp
    Le code assembleur sera fourni dans un fichier nommé fichier_a_compiler.s
    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
    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
    Hum, ouaip koala je connais bien l'option -S, seulement elle n'est pas dispo sous code::blocks. Et à ma connaissance sans cygwin on peut pas appellé mingw directement en console sous windows.
    Bref je booterais sous nux histoire de voir le code asm produit.

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 398
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 398
    Par défaut
    Citation Envoyé par Goten Voir le message
    Et à ma connaissance sans cygwin on peut pas appellé mingw directement en console sous windows.
    C'est faux, je l'ai déjà fait.
    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.

Discussions similaires

  1. Réponses: 2
    Dernier message: 04/08/2014, 13h43
  2. [PC portable] Différence de performance entre processeur 2 Ghz et 2,5 GHz
    Par debdev dans le forum Ordinateurs
    Réponses: 5
    Dernier message: 02/11/2009, 12h41
  3. Différence de performance entre localhost et serveur
    Par Borowsky dans le forum Décisions SGBD
    Réponses: 5
    Dernier message: 10/09/2009, 00h56
  4. Différence de performance entre JOIN et Subselect ?
    Par guidav dans le forum Requêtes
    Réponses: 1
    Dernier message: 20/07/2007, 10h01
  5. [TP] Entier 32 bits non signé
    Par SkaMan dans le forum Turbo Pascal
    Réponses: 6
    Dernier message: 24/08/2005, 22h17

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