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

Langage C++ Discussion :

Deux programmes avec des performances paradoxales


Sujet :

Langage C++

  1. #21
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 766
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 766
    Par défaut
    Bonjour Luc Hermitte,

    Citation Envoyé par Luc Hermitte Voir le message
    ...Pour le modulo, à nouveau ce que je cherche à montrer c'est que les compilateurs vont générer exactement le même asm si on utilise `%` ou si on calcule `a - (a/b) * b` depuis du C++...
    Je vais un peu pinailler .

    Cet exemple n'est pas complet. Le code a - (a/b) * b n'a jamais été intéressant. Dès le départ, la division (monde Intel) donnait le quotient et le reste (le modulo) dans des registres différents. Alors a % b générait 1 division tandis que a - (a/b) * b demandait 1 division, 1 multiplication et 1 soustraction.

    En revanche, le code q = a / b; r = a % b; (alors 2 divisions) était effectivement remplacé par q = a/b; r = a - q*b (1 division, 1 multiplication et 1 soustraction - intéressant car la division est beaucoup plus coûteuse que la multiplication). Aujourd'hui, pour peu que les calculs de q et r ne soient pas trop distants l'un de l'autre, ces deux instructions ne génèrent que 1 division dont elles se partagent les résultats. Utiliser DivMod évite de prendre le risque de perdre cette optimisation du compilateur.

    Salut

  2. #22
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 317
    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 317
    Par défaut
    Re,

    Effectivement, quand je fais référence à ce que j'ai écrit, c'est en contexte que l'on a aussi calculé a/b en vue de l'exploiter également

    Du coup, si on craint que le compilo ne sache pas optimiser (instructions dans des fonctions différentes?), le standard offre aussi `std::div`
    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...

  3. #23
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2012
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 96
    Par défaut
    # Luc Hermitte
    Par curiosité, j'ai regardé les implémentations de libstdc++ et de libc++.
    j'ai essayé mais je n'ai pas trouvé comment voir ces implémentations

    # tous
    J'ai utilisé un benchmark en ligne (Quick C++ Benchmark) pour comparer mon gcd binaire et std::gcd
    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
    39
    40
     
    #include <numeric>
     
    uint64_t gcd64(uint64_t u, uint64_t v)
    {
       if(u == 0) return(v);
       if(v == 0) return(u);
       int k = __builtin_ctzll(u | v);
       u >>= __builtin_ctzll(u);
       v >>= __builtin_ctzll(v);
       // now u and v are odd
       while( u != v ){
          if(u > v){
             u -= v;
             u >>=__builtin_ctzll(u);
          }else{
             v -= u;
             v >>= __builtin_ctzll(v);
          }
       }
       return(u << k);
    }
     
    static void std_gcd(benchmark::State& state) {
      uint64_t u, v, w;
      for (auto _ : state) {
        w = std::gcd(u,v);
        benchmark::DoNotOptimize(w);
      }
    }
    BENCHMARK(std_gcd);
     
    static void bin_gcd(benchmark::State& state) {
     uint64_t u, v, w;
      for (auto _ : state) {
        w = gcd64(u,v);
        benchmark::DoNotOptimize(w);
      }
    }
    BENCHMARK(bin_gcd);
    Sur ce benchmark, le binaire est 20% plus rapide que le std
    Nom : benchmark_gcc75.JPG
Affichages : 58
Taille : 27,5 Ko
    Une bizarrerie avec Clang
    Nom : benchmark_clang75.JPG
Affichages : 68
Taille : 26,8 Ko
    Je n'ai pas testé nanobench ; il n'est pas en ligne apparemment.

    Mes tests perso donnent des résultats très différents (option O3)
    Avec des données en 16 bits, 32 bits et 64 bits le gcd binaire est respectivement
    8.8 fois, 7.4 fois et 6.4 fois plus rapide que std
    Pour calculer les temps, j'utilise __rdtsc(). Pour un couple de valeurs (u, v) donné, Je boucle 10000 fois pour obtenir une valeur stable (j'ai essayé avec 1000000, ça ne change rien) et je boucle avec 10000 couples aléatoires (on peut faire plus mais c'est plus long !). Bon c'est du bricolage mais on est loin des 20% !

  4. #24
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2012
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 96
    Par défaut
    Update : j'ai chargé la dernière version de Code::Blocks et j'en ai profité pour changer de compilateur (MinGW_w64). Mon bricolage est cette fois plus conforme aux 20% du benchmak.
    Je passe ce fil en "Résolu".

    Par contre, si ceux qui m'ont si gentiment répondu pouvait jeter un coup d'oeil à mon nouveu fil "Problème de compilation avec l'option O3" ce serait super.

    Quoi qu'il en soit, grand merci à vous tous.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. installer deux programme avec Inno Setup
    Par bnisaid dans le forum Installation, Déploiement et Sécurité
    Réponses: 2
    Dernier message: 09/06/2008, 19h50
  2. Réponses: 3
    Dernier message: 17/12/2007, 11h58
  3. Réponses: 2
    Dernier message: 26/03/2007, 13h05
  4. Lancer un programme avec des arguments via IE...
    Par petozak dans le forum Général Conception Web
    Réponses: 6
    Dernier message: 24/03/2006, 12h51
  5. [Classpath][execution] executer un programme avec des jar.
    Par LoLoSS dans le forum Général Java
    Réponses: 11
    Dernier message: 26/08/2004, 12h45

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