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 :

Optimisation de code


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 31
    Par défaut Optimisation de code
    Bonjour tous,

    Voila j'aimerai optimiser le code ci dessous, pour donner une idée une multiplication en moins dans la 3eme boucle for c'est 1s de temps de calcul mon rêve serait de pouvoir supprimer la racine carre ^^ sachant que je connais a^2 je voudrais a^3

    Notes:
    - les vecteurs sont des classes de Eigen3
    - TmpParamForBS c'est des constantes pré-calculées
    - Cette fonction réalise une intégration en type double.

    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
     
    void Truc::get_precalc_B_optimized(const Vector3d & m, Vector3d & b,const TmpParamForBS & tmp)
    {
        Vector3d OM=Mrot.transpose()*(m-pos);
        b=Vector3d(0,0,0);
     
        double omx=OM[0];
        double omy=OM[1];
        double omz=OM[2];
        double omx_dl2_L2=omx-tmp.dl2_L2;
     
        std::vector<double> rx_list(tmp.rk);
        for(int k=0;k<tmp.rk;k++) rx_list[k]=(-k*tmp.dl+omx_dl2_L2);
        std::vector<double> rx2_list(tmp.rk);
        for(int k=0;k<tmp.rk;k++) rx2_list[k]=rx_list[k]*rx_list[k];
     
        for(int i=0;i<tmp.ri;i++)
        {
            double alpha=i*tmp.dtheta+tmp.dtheta2;
            double co=cos(alpha);
            double si=sin(alpha);
     
            for(int j=0;j<tmp.rj;j++)
            {
                Vector3d Btemp(0,0,0);
                double ray = j*tmp.de+tmp.R_de2;
                double omy_ray_c = omy-ray*co;
                double omz_ray_s = omz-ray*si;
                double si_r2_co_r1 = si*omz_ray_s+co*omy_ray_c;
                double omy_ray_c2_omz_ray_s2 = omy_ray_c*omy_ray_c+omz_ray_s*omz_ray_s;
     
                for(int k=0;k<tmp.rk;k++)
                {
                    double rx=rx_list[k];
                    double nr2=rx2_list[k]+omy_ray_c2_omz_ray_s2;
                    double nr= sqrt(nr2);
                    //if(nr>quantom_zero)
                    {
                        Btemp+= Vector3d(si_r2_co_r1, -co*rx, -si*rx)/(nr2*nr);
                    }
                }
     
                b+= (tmp.tmp1*j + tmp.tmp2)*Btemp;
            }
        }
        b*=Mu0_Pi4*tmp.J ;
        b=Mrot*b;
    }
    Je suis preneur de toute idée

    merci d'avance pour vos suggestions.

  2. #2
    Membre confirmé
    Inscrit en
    Avril 2013
    Messages
    93
    Détails du profil
    Informations forums :
    Inscription : Avril 2013
    Messages : 93
    Par défaut
    Salut,

    Je te conseillerai déjà de déclarer toutes tes variables double (ray, omy_ray_c, ...) en-dehors des boucles. Comme ça tu ne les déclare qu'une seule fois et pas, dans le pire des cas, tmp^3.

    J'essayerai de calculer les indices 2 et 3 de Vector3d plus tot. Je sais pas si ce que je te propose est correct, j'ai fait vite fait.

    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
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
     
    void Truc::get_precalc_B_optimized(const Vector3d & m, Vector3d & b,const TmpParamForBS & tmp)
    {
        Vector3d OM=Mrot.transpose()*(m-pos);
        b=Vector3d(0,0,0);
     
        double omx=OM[0];
        double omy=OM[1];
        double omz=OM[2];
        double omx_dl2_L2=omx-tmp.dl2_L2;
     
        std::vector<double> rx_list(tmp.rk);
        for(int k=0;k<tmp.rk;k++) 
    		rx_list[k]=(-k*tmp.dl+omx_dl2_L2);
     
        std::vector<double> rx2_list(tmp.rk);
     
    	for(int k=0;k<tmp.rk;k++) 
    		rx2_list[k]=rx_list[k]*rx_list[k];
     
    	//++++++
    	std::vector<double> vecTmp1(tmp);
    	std::vector<double> vecTmp2(tmp);
     
    	double omy_ray_c = 0.0;
    	double omz_ray_s = 0.0;
    	double omy_ray_c2_omz_ray_s2 = 0.0;
    	double ray = 0.0;
     
    	double rx = 0.0;
    	double nr2 = 0.0;
    	double nr = 0.0;
            double ray = 0.0;
            double si_r2_co_r1 = 0.0;
    	//++++++
     
    	for(int i=0;i<tmp.ri;i++)
    	{
    		double alpha=i*tmp.dtheta+tmp.dtheta2;
    		double co=cos(alpha);
    		double si=sin(alpha);
     
    		//++++++
    		for(int k=0;k<tmp.rk;k++)
    		{
    			vecTmp1[k] = -co*rx_list[k];
    			vecTmp2[k] = -si*rx_list[k];
    		}		
    		//++++++
     
    		for(int j=0;j<tmp.rj;j++)
    		{
    			Vector3d Btemp(0,0,0);
     
    			ray = j * tmp.de + tmp.R_de2;
     
    			omy_ray_c = omy - ray * co;
    			omz_ray_s = omz - ray * si;
    			omy_ray_c2_omz_ray_s2 = omy_ray_c * omy_ray_c + omz_ray_s * omz_ray_s;
     
    			si_r2_co_r1 = si * omz_ray_s + co * omy_ray_c;
     
    			for(int k=0;k<tmp.rk;k++)
    			{
    				nr2 = rx2_list[k] + omy_ray_c2_omz_ray_s2;
    				nr = sqrt(nr2);
     
    				//if(nr>quantom_zero)
    				{
    					Btemp += Vector3d(si_r2_co_r1, vecTmp1[k], vecTmp2[k]) / (nr2*nr);
    				}
    			}
    			bFirst = false;
     
                b+= (tmp.tmp1*j + tmp.tmp2)*Btemp;
            }
        }
        b*=Mu0_Pi4*tmp.J ;
        b=Mrot*b;
    }

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 152
    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 152
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par pepito3364 Voir le message
    Je te conseillerai déjà de déclarer toutes tes variables double (ray, omy_ray_c, ...) en-dehors des boucles. Comme ça tu ne les déclare qu'une seule fois et pas, dans le pire des cas, tmp^3.
    Je suis pas sûr qu'il y ait un quelconque intérêt pour un type primitif.
    C'est l'appel à un constructeur/destructeur qui est pénalisant.
    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.

  4. #4
    Membre confirmé
    Inscrit en
    Avril 2013
    Messages
    93
    Détails du profil
    Informations forums :
    Inscription : Avril 2013
    Messages : 93
    Par défaut
    ça va dépendre du compilateur et notamment des options de compilation. Mais j'ai déjà observé des gains de perf avec ce genre de petites optim.
    Je suis pas expert, mais j'ai l'impression que le compilateur n'a pas besoin de remettre la variable sur un registre et vu le nombre de variable dans la fonction, on doit pouvoir utiliser un registre pour une variable. Certains compilateur doivent gérer ça correctement je suppose.
    Il faudrait voir le code asm dans les 2 cas.

  5. #5
    Membre Expert Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 048
    Par défaut
    A ce stade là, tu obtiendras plus de performance en travaillant sur l'organisation mémoire de tes données (bloc contigüe en mémoire, faire le moins de saut possible dans le bloc, surtout valable avec les boucles for dans une autre boucle for, fais un maximum de traitement sur des mémoires contigües)
    Sinon un petit truc mais bon tu vas pas avoir de grande différence je pense;
    Ce code la:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    std::vector<double> rx_list(tmp.rk);
    for(int k=0;k<tmp.rk;k++) 
        rx_list[k]=(-k*tmp.dl+omx_dl2_L2);
     
    std::vector<double> rx2_list(tmp.rk);
     
    for(int k=0;k<tmp.rk;k++) 
        rx2_list[k]=rx_list[k]*rx_list[k];
    Deviens:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for(int k=0;k<tmp.rk;++k)
    {
        double val = (-k*tmp.dl+omx_dl2_L2);
        rx_list[k]=val;
        rx2_list[k]=val*val;
    }
    Et enlève tout tes x++ et mets les en ++x. Certain compilateur sont assez intelligent pour optimiser la première version mais ne joue pas avec le feu

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Fais un reserve() sur Btemp.

  7. #7
    Membre émérite
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2009
    Messages : 552
    Par défaut
    Citation Envoyé par Astraya Voir le message
    A ce stade là, tu obtiendras plus de performance en travaillant sur l'organisation mémoire de tes données (bloc contigüe en mémoire, faire le moins de saut possible dans le bloc, surtout valable avec les boucles for dans une autre boucle for, fais un maximum de traitement sur des mémoires contigües)
    A ce titre, fusionner ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    std::vector<double> vecTmp1(tmp);
    std::vector<double> vecTmp2(tmp);
    en

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    std::vector< std::pair< double, double > > vecTmp12 ;
    ça aiderait en plein cœur des boucles ou ça ne sert à rien?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    // avant vecTmp1[k] et vecTmp2[k] ne sont pas forcément proche
    Btemp += Vector3d(si_r2_co_r1, vecTmp1[k], vecTmp2[k]) / (nr2*nr);
     
    // après vecTmp1[k].first et vecTmp2[k].second se suivent en mémoire
    Btemp += Vector3d(si_r2_co_r1, vecTmp1[k].first, vecTmp2[k].second) / (nr2*nr);

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 31
    Par défaut
    ...

    J'essayerai de calculer les indices 2 et 3 de Vector3d plus tot. Je sais pas si ce que je te propose est correct, j'ai fait vite fait.
    Effectivement c'est une optimisation, merci bien vu!

    J'ai déjà essayer de sortir la déclaration des variables des boucles mais cela ne change rien ...

    Et enlève tout tes x++ et mets les en ++x. Certain compilateur sont assez intelligent pour optimiser la première version mais ne joue pas avec le feu
    C'est vrai ... pris bonne note , mais cela n'a pas changé grand chose.

  9. #9
    Membre confirmé
    Inscrit en
    Avril 2013
    Messages
    93
    Détails du profil
    Informations forums :
    Inscription : Avril 2013
    Messages : 93
    Par défaut
    C'est déjà ça, sinon je voit pas comment gagner sur la racine..
    Tu as pensé à utiliser la parallélisation? il faudrait faire attention à l'écriture sur "b" mais avec des mutex ça passe.
    Bon courage pour la suite

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 31
    Par défaut
    Citation Envoyé par pepito3364 Voir le message
    C'est déjà ça, sinon je voit pas comment gagner sur la racine..
    Tu as pensé à utiliser la parallélisation? il faudrait faire attention à l'écriture sur "b" mais avec des mutex ça passe.
    Bon courage pour la suite
    Oui tu as raison, mais ca complique pas mal le code ... j'ai pas trop envie de m'engagé sur cette voie sur cette fonction ... surtout que le programme est deja multithreadé .

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

Discussions similaires

  1. optimiser le code d'une fonction
    Par yanis97 dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 15/07/2005, 08h41
  2. Optimiser mon code ASP/HTML
    Par ahage4x4 dans le forum ASP
    Réponses: 7
    Dernier message: 30/05/2005, 10h29
  3. optimiser le code
    Par bibi2607 dans le forum ASP
    Réponses: 3
    Dernier message: 03/02/2005, 14h30
  4. syntaxe et optimisation de codes
    Par elitol dans le forum Langage SQL
    Réponses: 18
    Dernier message: 12/08/2004, 11h54
  5. optimisation du code et var globales
    Par tigrou2405 dans le forum ASP
    Réponses: 2
    Dernier message: 23/01/2004, 10h59

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