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

SL & STL C++ Discussion :

std::complex lent ?


Sujet :

SL & STL C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut std::complex lent ?
    Bonjour.
    Pour ecrire un bout de code fractal, j'ai voulue utiliser std::complex. Seulement c'est beaucoup plus lent que d'ecrire le calcul à la main
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    double zx = xf + xRatio*j;
    double zy = yf + yRatio*i;
    double cx = zx;
    double cy = zy;
     
    while(buf[j]<itermax && zx*zx+zy*zy<4)
                {
    		double xnew = zx * zx - zy * zy + cx;
    		zy = (2 * zx * zy )+ cy;
                    zx = xnew;
                    ++(buf[j]);
     
                }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    z = c = std::complex<double>( xf + xRatio*j, yf + yRatio*i) ;	
    while(buf[j]<itermax && std::abs(z)<4)
                {
                    z = z*z+c;
                    ++(buf[j]);
     
                }
    es ce normale? je développe sous visual c++ 2008 express

  2. #2
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    J'ai trouvé cela :
    http://www.ddj.com/linux-open-source/199702312?pgno=1

    Application of std::complex<T> could result in some shorter code, but the computational performance, which I try to maximize, would be lost.

    y as rien a faire??

  3. #3
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 967
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 967
    Par défaut
    Goe,
    Citation Envoyé par Mongaulois Voir le message
    y as rien a faire??
    Si, coder toi-même ce qu'il faut, c'est à dire pas grand chose au total, en fait.

    En évitant de faire une classe si la vitesse est primordiale, ce sera toujours ça de gagné (structure + les fonctions ad-hoc est suffisant [Je vais me faire insulter par les puristes, mais il faut savoir ce qu'on veut]).

  4. #4
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    En faite ce qui me choque c'est que c'est 5 à 10 fois plus lent avec les complex!!!!
    je trouve cela enorme!!! non?
    je m'attendais à quasiment le même temp

  5. #5
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    y aurais peut être une début d'explication
    http://readlist.com/lists/gcc.gnu.or...help/0/12.html

    ce serait à cause du test
    std::abs(z)<4
    Faudra que je teste

    [edit]
    http://shootout.alioth.debian.org/gp...ng=gcc%20&id=3
    C'est bien sensé donner de trés bon resultat
    http://shootout.alioth.debian.org/gp...&lang=gpp&id=0

  6. #6
    Membre émérite

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Par défaut
    Cela n'a rien à voir avec les complexes. La différence de temps viens du fait que les deux codes ne font pas la même chose : le premier compare la norme au carré, le second la valeur absolue, c-à-d fait appel à sqrt().

  7. #7
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par Sylvain Togni Voir le message
    Cela n'a rien à voir avec les complexes. La différence de temps viens du fait que les deux codes ne font pas la même chose : le premier compare la norme au carré, le second la valeur absolue, c-à-d fait appel à sqrt().
    Ha oui merci, je me suis embrouillé entre abs et norm

    Normalement j'avais aussi essayé avec std::norm et c'était pareil...
    Je vais vérifier ce soir

  8. #8
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    Pas tant que ça... c'est pas du tout le même code !

    Regardons les codes:
    Ton code:
    Code C++ : 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
     
    double zx = xf + xRatio*j;
    // 1 addition, 1 multiplication
    double zy = yf + yRatio*i;
    // 1 addition, 1 multiplication
    double cx = zx;
    // 0
    double cy = zy;
    // 0
     
    while(buf[j]<itermax && zx*zx+zy*zy<4) 
    {
           // 1 indirection (pas en release), 2 comparaisons, 2 multiplications, 3 additions
           double xnew = zx * zx - zy * zy + cx;
           // 2 multiplications, 1 addition  A noter qu'en mode release, le compilo ne fait pas les 2 multiplications (déjà effectuées pour le test de la boucle)
           zy = (2 * zx * zy )+ cy;
           // 2 multiplications, 1 addition
           zx = xnew;
           // 1 affectation
           ++(buf[j]);
           // 1 incrémentation (à noter qu'en mode release cette opération est fait sur un registre qui est affecté après la boucle)
    }
    Résultat, disons pour 10 itérations: 52 additions, 42 multiplications, 20 comparaisons, 1 affectation avec indirection

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    z = c = std::complex<double>( xf + xRatio*j, yf + yRatio*i) ;
    // idem code précédant
    while(buf[j]<itermax && std::abs(z)<4)
    {
          // std::abs == sqrt(std::norm(z))
          // donc: 2 comparaisons, 2 multiplications, 3 additions, 1 square-root
          z = z*z+c;
          // le compilo n'a pas fait d'optimisation ici: 
          // donc: 4 multiplications (2 par opérande du z*z), 4 additions (2 par opérande du z*z et 2 pour le +c)
          // a rajouter 1 construction temporaire d'objet, et 2 affectations
          ++(buf[j]);
          // idem code précédant
    }
    D'une part la condition de sortie de la boucle n'est pas la même (equivalent à <16 dans le premier code), ce qui doit induire plus d'itérations.
    Même à nombre d'itération identique (10) on aura:
    72 additions, 62 multiplications, 20 comparaisons, 21 affectations, 10 créations d'objet temporaire, 10 square-root

  9. #9
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par nicroman Voir le message
    Pas tant que ça... c'est pas du tout le même code !
    Merci, très intéressant.
    Par contre

    double xnew = zx * zx - zy * zy + cx;
    // 2 multiplications, 1 addition A noter qu'en mode release, le compilo ne fait pas les 2 multiplications (déjà effectuées pour le test de la boucle)
    moi je voie 2 multiplications et 2 addition (et 1 changement de signe )
    ce qui ferait avec la seconde instruction :
    4 multiplication et 3 addition

    z = z*z+c;
    // le compilo n'a pas fait d'optimisation ici:
    // donc: 4 multiplications (2 par opérande du z*z), 4 additions (2 par opérande du z*z et 2 pour le +c)
    // a rajouter 1 construction temporaire d'objet, et 2 affectations
    pourquoi ne serait'il pas optimiser et comment tu trouve
    4 multiplications (2 par opérande du z*z), 4 additions (2 par opérande du z*z et 2 pour le +c)

  10. #10
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    voici un code de teste :
    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
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    #include <iostream>
    #include <fstream>
    #include <complex>
    #include <ctime>
     
    int main(int argc, char* argv[])
    {
        const int w = 1000;
        const int h = 1000;
        const int iterMax = 1000;
        const double p[] ={-2.,-2.};
        const double size[] ={4.,4.};
     
        const double xRatio =size[0]/(w-1);
        const double yRatio =size[1]/(h-1);
     
        std::complex<double> z;
        std::complex<double> c;
     
     
        int * pBuffer = new int[w*h];
     
        int t1 = clock();
        for (int i=0;i<h;++i)
        {
            for (int j=0;j<w;++j)
            {
            int id = i*w+j;
            int & refRes = pBuffer[id];
            refRes =0;
     
            z = c = std::complex<double>( p[0] + xRatio*j, p[1] + yRatio*i) ;
            while(refRes<iterMax && std::norm(z)<4)
                {
                #if 1
                    z = z*z+c;
                #else
                    z*=z;
                    z+=c;
                #endif
                    ++refRes;
                }
            if (refRes==iterMax) refRes =0;
     
            }
        }
        std::cout<< (double)(clock() - t1)/CLOCKS_PER_SEC<<std::endl;
     
     
        std::ofstream fout("image.pgm");
        fout<<"P2"<<std::endl;
        fout<<w<<" "<<h<<std::endl;
        fout<<"256"<<std::endl;
        const double max =.1*iterMax;
        for (int i=0;i<w*h;++i)
        {
            fout<<(int)(255.*(pBuffer[i]>max ? 1. : (double)pBuffer[i]/max))<<" ";
        }
     
     
     
        system("pause");
     
    	return 0;
    }
    methode 1 : z =z*z+c
    methode 2 : z =*z; z+=c;

    avec mingw :
    methode 1 : a peu prés 7
    methode 2 : a peu prés 6.5

    avec visual 2005 :
    methode 1 : a peu prés 12.5
    methode 2 : a peu prés 3.5

Discussions similaires

  1. std::sort lent pour les short int
    Par piedintelligent dans le forum SL & STL
    Réponses: 5
    Dernier message: 27/01/2012, 18h39
  2. std::complex / ISO C++ / C99 / C++Ox ?
    Par nikopol82 dans le forum SL & STL
    Réponses: 6
    Dernier message: 19/01/2010, 09h53
  3. [1.x] Symfony trop lent/complexe ?
    Par ymoreau dans le forum Symfony
    Réponses: 3
    Dernier message: 25/06/2009, 08h54
  4. [std::ifstream] Lecture formatée lente
    Par HanLee dans le forum SL & STL
    Réponses: 15
    Dernier message: 31/05/2009, 01h35
  5. [win2003 std]Apply Personnal settings LENT !
    Par ChristopheOce dans le forum Windows Serveur
    Réponses: 2
    Dernier message: 14/05/2007, 12h48

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