begin process at 2012 05 30 00:50:02
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Archive C/C++

 > 

Archives

 > 

Maths & Algorithmes

 > 

Optimisation de programmes en C/C++


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Optimisation de programmes en C/C++

mardi 17 janvier 2006 à 17:44:11 | Optimisation de programmes en C/C++

alexgintz


Bonjour, j'ai développé sous DevC++5 un programme de "méthode des images" pour accélérer mes simulations du champ acoustique (la connaissance du but du programme n'est pas nécessaire à la compréhension du problème) jusqu'ici faites sous Matlab (un logiciel de calcul scientifique basé sur un language de programmation + évolué que le C). A ma grande surprise, le programme en C/C++ même optimisé (à ma sauce, je ne suis pas un pro) va moins vite que celui sous Matlab... l'effet désiré n'étant pas atteint!
Le coeur du programme qui prend le plus de temps est le suivant:

    ///////////////////////////////
    // DEMARRAGE DE L'ALGORITHME //
    ///////////////////////////////
    ofstream p_fichier_H ("H.txt");
    // Debut boucle sur la fréquence:
    for (nf = 0 ; nf <= Nf - 1 ; nf++ )
    {
        Cst = j/deux*f[nf]*Rho;
       
        // Debut boucle sur la position des sources:
        for (ns = 0 ; ns <= Ns - 1 ; ns++ )
        {
            // Debut boucle sur axe X des sources-images:
            for (m = -ORDRE[nf] ; m <= ORDRE[nf] ; m++ )
            {
                // Debut boucle sur axe Y des sources-images:
                for (n = -ORDRE[nf] ; n <= ORDRE[nf] ; n++ )
                {
                    // Debut condition nombre reflexions sur les murs:
                    if ((abs(m)+abs(n)) <= ORDRE[nf])
                    {
                    // Debut boucle sur axe Z des sources-images:
                    for (p = -ORDRE[nf] ; p <= ORDRE[nf] ; p++ )
                    {
                        // Debut condition nombre reflexions sur les murs:
                        if ((abs(m)+abs(n)+abs(p)) <= ORDRE[nf])
                        {
                        // Calcul des projections de la distance origine - source-image:
                         Six = m * Lx + pow( -1.0 , m ) * Sx[ns] ;
                         Siy = n * Ly + pow( -1.0 , n ) * Sy[ns] ;
                         Siz = p * Lz + pow( -1.0 , p ) * Sz[ns] ;
                         // Debut boucle sur la position des Micros:
                        for (nmic = 0 ; nmic <= Nmic-1 ; nmic++ )
                        {
                           // Calcul des projections de la distance micro - source-image:
                           Rx = Six - Mx[nmic] ;
                           Ry = Siy - My[nmic] ;
                           Rz = Siz - Mz[nmic] ;
                           // Calcul de la distance micro - source-image:
                           R = sqrt( pow( Rx , 2 ) + pow( Ry , 2 ) + pow( Rz , 2 ) ) ;
                           // Calcul des impédances de surface selon chaque axe:
                           Zx = Zsurf[nf] * abs( Rx ) / R / Zc;
                           Zy = Zsurf[nf] * abs( Ry ) / R / Zc;
                           Zz = Zsurf[nf] * abs( Rz ) / R / Zc;
                           // Somme la contribution de la source(m,n,p) à la fréq(nf) sur le micro(nmic):
                           Ptot[nmic] = Ptot[nmic] + Cst*exp(-j*deux*pi*f[nf]*R/C)/R
                                      *cpx_pow_dbl(( Zx - un ) / ( Zx + un ) , abs(m))
                                      *cpx_pow_dbl(( Zy - un ) / ( Zy + un ) , abs(n))
                                      *cpx_pow_dbl(( Zz - un ) / ( Zz + un ) , abs(p));
                           //           *cpx_pow_dbl(( Zx - un ) / ( Zx + un ) , abs(m))
                           //           *cpx_pow_dbl(( Zy - un ) / ( Zy + un ) , abs(n))
                           //           *cpx_pow_dbl(( Zz - un ) / ( Zz + un ) , abs(p));
                        // Fin boucle position des Micros
                        }
                        // Fin condition nombre reflexions sur les murs
                        }
                    // Fin boucle sur axe Z des sources-images
                    }
                    // Fin condition nombre reflexions sur les murs
                    }
                // Fin boucle sur axe Y des sources-images
                }
            // Fin boucle sur axe X des sources-images
            }
            //////////////////////////////////////////
            // Ecriture des données puis remise à 0: /
            //////////////////////////////////////////
            // Debut boucle Micros
            for (nmic = 0 ; nmic <= Nmic-1 ; nmic++ )
            {
                p_fichier_H << real(Ptot[nmic]) << "\t" << imag(Ptot[nmic]) << "\t";
                // Remise à zero du vecteur:
                Ptot[nmic] = (0.0,0.0);
            // Fin boucle Micros
            }
            p_fichier_H << endl;
        // Fin boucle sur la position des sources
        }
    // Fin boucle sur la fréquence
    }
    p_fichier_H.close();
 
qui fait appel à la fonction:

    complex<double> cpx_pow_dbl(complex<double> x, double n)
    {           
             //complex<double> y = pow(abs(x), n)*exp(n*j*arg(x));
             return pow(abs(x), n)*exp(n*j*arg(x));
    }

qui a l'air de prendre pas mal de temps.

Je me demande donc comment est-ce possible que mon programme soit plus lent et je vous demande si qqu'un a une idée pour accélérer les calculs.
Merci d'avance...

AlexG

mardi 17 janvier 2006 à 18:04:04 | Re : Optimisation de programmes en C/C++

sibi12

Un amélioration possible serait de faire x*x au lieu de pow(x,2). Sinon pow(-1,m) c'est bien pour écrire ça mathématiquement mais au niveau du processeur c'est pas géniale du tout. fait plutot m & 1 ? -1 : 1.

et puis il y a quelque expression comme -j*deux*pi*f[nf]*R/C qui peuvent etre accélerer en gardant la valeur de -j*deux*pi*R/C en mémoire.

Il est très important quand tu as autant de boucle imbriqué d'optimiser le code au maximum. Regarde du coté de l'assembleur si il n'y a pas moyen de faire mieux que ce que le compilo te donne.

XbY

mardi 17 janvier 2006 à 20:22:58 | Re : Optimisation de programmes en C/C++

BruNews

Administrateur CodeS-SourceS
Donne ce que tu veux en PSEUDO code et surtout le but à atteindre mais pas ton code si tu veux qu'on t'en ponde un autre.

ciao...
[ Lien ]
BruNews, MVP VC++
mardi 17 janvier 2006 à 22:53:41 | Re : Optimisation de programmes en C/C++

Galmiza

R = sqrt( pow( Rx , 2 ) + pow( Ry , 2 ) + pow( Rz , 2 ) ) ;
=>
R = sqrt(Rx*Rx+Ry*Ry+Rz*Rz);


Zx = Zsurf[nf] * abs( Rx ) / R / Zc;
Zy = Zsurf[nf] * abs( Ry ) / R / Zc;
Zz = Zsurf[nf] * abs( Rz ) / R / Zc;
=>
double c = Zsurf[nf] / R / Zc;
Zx = c*abs(Rx);
Zy = c*abs(Ry);
Zz = c*abs(Rz);


Et dans les boucles, préfère i<N que i<=N-1 ça t'evitera des décrementation à chaque boucle pour faire la comparaison.
De façon générale, n'hésite pas à déclarer des variables suplémentaires pour stocker des résultats intermédiaires utilisés plusieurs fois (exemple du double c).

Et puis tes abs(n), tu les calcules sans arrêt !
Crée une variable absn = abs(n).
mardi 17 janvier 2006 à 22:56:36 | Re : Optimisation de programmes en C/C++

Galmiza

A la limite remplace tes for par des do - while(i--).

i=1000;
do
{
}
while (i--)

est directement transcrit en assembleur (du moins en assembleur 68000).

mov r0,#999
\lbl

dbra r0, \lbl

mercredi 18 janvier 2006 à 11:45:15 | Re : Optimisation de programmes en C/C++

alexgintz

Bon, tout d'abord Merci à tous, c'est sympa de vous occuper de moi!
Alors pour qu vous ayez un retour sur investissement, je vous dirais que:
- "
pow(x,2) --> x*x" fait gagner qques 100msec/35sec,
- "
pow(-1,m) --> bool(m) & 1 ? -1 : 1" fait gagner 1 à 2 sec/35sec,
- "
for(i=....) --> do{}while(i...)" ne fait pas gagner de temps,
- la déclaration de variables intermédiaires fait gagner qques 100msec/35sec,
- mais ce qui m'a fait gagner le plus de temps, c'est de déclarer mes indices "
m, n et p" en int et de les convertir ensuite à l'interieur de la fonction cpx_pow_dbl en double, alors qu'au début je les avait déclaré en double pour ne pas les convertir ensuite, jugeant que ca allait etre plus long...  vous allez me dire que c'est trivial, mais en fait pas pour tout le monde... (j'ai gagné tout de même 4sec/35sec).
Mais en général, je suis décu de voir que finallement, meme en se donnant du mal, on n'arrive pas à faire plus rapide que les languages de haut niveau... et que les tutoriaux sur l'optimisation des codes, c'est à dire qui permettraient d'avoir une idée des stratégies pour gagner du temps n'encombrent pas internet.

Merci encore
AlexG

samedi 11 février 2006 à 01:16:32 | Re : Optimisation de programmes en C/C++

cutibipoulet

Je voudrai juste signaler une chose qui me parait évedente dans ce genre de problème. Au lieu de gagner au final quelques secondes, avec des while(i--) des (bool(m) & 1) ?-1:1 ... ou autres choses... il faudrai tout simplement que tu revois ton algorithme ! La programmation n'est pas une question de savoir coder en assembleur ou de donner un code optimiser a 100 au niveau des instructions, il faut donner le bon algorithme ! Je ne comprend pas ton raisonnement qui consiste a dire : mon prog va moin vite que sous matlab donc jvé optimiser les commandes... au final tu fé un programme lent et moche... enfin jte jette pas la pierre je dis juste que l'algo est plus important que l'optimisation de code !
alors refé ton algo et après tu va voir tu va gagner en vitesse plus que tu pourrait gagner en assembleur avec ton truc. 
Sinon, juste quand tu cast en bool ca marche peut etre mais c'est bof ... même très très bof surtout pour faire une opération binaire juste après... tu sais ce que s'est au moin bool ? et l'opérteur & ? donc la ya un truc qui va pas... (d'ailleur jviens de vérifier ca ne marche absolument pas chez moi... )

d'ailleur sibi 28 avait donné la "bonne" solution : ( m & 1 )? -1 : 1;



enfin juste pour pousser un ptit coup de gueule au gens qui pense trop a optimiser leurs code et non leurs algo... ++ et jespere tu aura une bonne note et que tu va regarder si tu peu optimiser l'algo plutot ++

++

 "et que les tutoriaux sur l'optimisation des codes, c'est à dire qui permettraient d'avoir une idée des stratégies pour gagner du temps n'encombrent pas internet. "
   => car cela ne sert pas surtout dans ton cas !
PS : si matlab va plus vite ke tu c pure ... c ke la il y a vraiment un problème d'algo...

samedi 11 février 2006 à 02:35:46 | Re : Optimisation de programmes en C/C++

Galmiza

Il est bien évident qu'avant d'optimiser le code il faut optimiser l'algo. L'optimisation du code permet de gagner quelques pourcent. Dans le cas d'Alex, il y a énormement de boucles donc l'optimisation de code est rapide (car peut de ligne) et justifiée (boucles, donc exécution de la même ligne de nombreuses fois).

Nous n'avons pas forcement le temps de décomposer le programme, d'essayer de comprendre le sens de chaque ligne, de déduire son objectif final et trouver une meilleure solution.

Mais effectivement l'amélioration de l'algorithme permet des gains énormes.
samedi 11 février 2006 à 10:29:01 | Re : Optimisation de programmes en C/C++

BruNews

Administrateur CodeS-SourceS
alexgintz > ce qui a été dit plus haut est fort exeact, l'algo d'abord et seulement ensuite on regarde si on peut encore gagnaer qlq chose.

ciao...
[ Lien ]
BruNews, MVP VC++


Cette discussion est classée dans : boucle, nf, abs, pow, nmic


Répondre à ce message

Sujets en rapport avec ce message

La boucle FOR [ par C++ ] Ou est l erreur svp :for (int i=0;i MessageBox (i); Intercepter la touche ESC [ par mindark ] BonjourVoila, j'ai un programme qui execute une boucle d'environ 5 mins. Et je voudrais que cette boucle soit executee plusieurs fois, jusqu'a ce que Problème avec une boucle while [ par arconius ] voilà j'ai fait un prog où l'on tire des dés mais j'ai un problème avec ma boucle while car au lieu de me donner un chiffre aléatoire à chaque fois il pourquoi aprés avoir fait une boucle mon textbackground prend tout l'écran ? [ par arconius ] Voila mon prog et après avoir fait une boucle mon text background prend tout l'écran si quelqu'un à une solution se serait sympa merci d'avance#includ Copie directe d'un tableau vers un autre (sans boucle) [ par NiFF ] Existe-t-il une fonction C qui me permettrait de copier un tableau vers un autre de même dimension,et ce sans avoir à traiter tous les items de ce tab boucle infinie,enfin presque... [ par booth ] bonjour, je suis semi newbie en C++, et je viens de faire un prog avec des sockets...le truc c'est que je suis obligé d'utiliser une boucle ainfinie p la fonction gotoxy(int abs,int ord) [ par jimtruand ] Salut !Je cherche la fonction equivalente a gotoxy(arg1,arg2) de borlandc++ sous Visualc++ ?C'est une fonction qui nous permet de placer le curseur ou Probleme de source pour un timer!!! Help!!! [ par superteta2003 ] Salut!J'ai créer un timer en C++ dans une application windows (MFC), et en le verrifiant manuellement, il doit marcher... Cependant, il y a une couill Debutant : Boucle et C :) [ par Tkaos ] Bonjour, Voila je suis nouveau ici et dans l'univers de la progz, Bon vais pas vous faire attendre, voici mon probleme : Comme je suis caremment novic Boucle infinie sans aucune raison apparente... [ par madcow41 ] Bonjour,Dans mon projet de C, je doit traiter un fichier Log d'un site.Seul problème, lors du traitement, mon programme se bloque, sans aucune raison


Nos sponsors


Sondage...

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

Photothèque

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,624 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales