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++

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    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 : 61
    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
    Points : 50 367
    Points
    50 367
    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)

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    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 sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 627
    Points : 30 692
    Points
    30 692
    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

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    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 sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 380
    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 380
    Points : 41 576
    Points
    41 576
    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.

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Et donc, comment?




    (le à ma connaissance, incluait que si quelqu'un savait comment faire j'étais ouvert à toute proposition, parce que ça peut être utile par moment.

  8. #8
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Euu dites les gens vous croyez vraiment qu'une bête changement de signed à unsigned peut déclencher une optimisation faisant passer un programme de 15min à 1 seconde.

    Y a juste un overflow sur node qui dépasse INT_MAX (les valeurs de la suite de Syracuse ça peut monter très haut avant de revenir à 1), donc node part dans les négatifs et on tombe sur une boucle infinie...

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    J'ai pas osé émettre l'hypothèse, ne sachant pas jusqu'où montait la suite de syracuse mais en effet ça me semble plus probable... Quoique... tu penses que ça peut dépasser les 2^32 pour une valeur de départ inférieur à 1 millions?

  10. #10
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Oui, ça ne m'étonnerait pas.
    Je me souviens plus jeune mettre acharné sur ma calculatrice pour vérifier que même un grand nombre, comme 1 million, revenait toujours à 1 (à la main, je ne connaissais pas la programmation à l'époque ) et j'avais vite abandonné car les valeurs montaient parfois vraiment très haut. Il y a un exemple sur la page wikipédia anglaise qui part de 27 et dépasse les 9000 par exemple.

  11. #11
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Bon je viens de tester rapidement au debuggeur et node passe effectivement dans les négatifs.

    Avec en prime une découverte mathématique majeure ! La conjecture de Syracuse est fausse pour les entiers négatifs ! La suite ne se stabilise pas autour de -1, mais fait des sortes de cycle .

  12. #12
    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 : 61
    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
    Points : 50 367
    Points
    50 367
    Par défaut
    Bon ben il faut passer au unsigned long long int. Avec 64 bits, tu devrait pouvoir aller plus loin.

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Bon après quelques tests pour affiché la valeur maximale de la suite, avec un unsigned int ou un unsigned long long j'ai pas la même valeur. Donc j'en déduit que si c'est passé avec un unsigned int (résultat juste) c'est un coup de chance.

    Donc pour un n<1000000 la suite de syracuse monte jusqu'à 569111483520.

  14. #14
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 627
    Points : 30 692
    Points
    30 692
    Par défaut
    Citation Envoyé par Goten Voir le message
    Et donc, comment?




    (le à ma connaissance, incluait que si quelqu'un savait comment faire j'étais ouvert à toute proposition, parce que ça peut être utile par moment.
    Tout simplement:

    Tu commence par rajouter le chemin Disque:\La\OuSeTrouve\Gcc\bin à ta variable PATH

    Procédure:
    menu démarrer->panneau de configuration->système->onglet "avancé"->cliquer sur le bouton "variables d'environnement":
    dans la liste "variables système", trouver la variable Path, cliquer sur modifier, aller en fin de ligne, rajouter un point virgule ";"suivi du chemin à suivre pour arriver au dossier bin du dossier gcc

    Par la suite, il te suffit de lancer une console
    procédure:
    menu démarrer->exécuter->taper "cmd" et cliquer sur "ok" ou
    menu démarrer->tous les programmes->accessoires->Invite de commandes

    Tu peux t'assurer que l'exécutable gcc est bien reconnu (et en profiter pour vérifier la version) en tapant "gcc -v"

    "YAPUKA" aller dans le dossier dans lequel se trouvent les fichier à compiler et à t'amuser

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Héhé, bien fait de parler moi :p. Merci bien, tout est en ordre .

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