alexgintz
Messages postés2Date d'inscriptionmercredi 7 décembre 2005StatutMembreDernière intervention18 janvier 2006
-
17 janv. 2006 à 17:44
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019
-
11 févr. 2006 à 10:29
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:
sibi12
Messages postés337Date d'inscriptionjeudi 19 décembre 2002StatutMembreDernière intervention15 avril 2006 17 janv. 2006 à 18:04
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.
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).
alexgintz
Messages postés2Date d'inscriptionmercredi 7 décembre 2005StatutMembreDernière intervention18 janvier 2006 18 janv. 2006 à 11:45
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.
cutibipoulet
Messages postés26Date d'inscriptionmardi 8 juin 2004StatutMembreDernière intervention20 mai 2007 11 févr. 2006 à 01:16
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...
Galmiza
Messages postés573Date d'inscriptionsamedi 16 novembre 2002StatutMembreDernière intervention 9 avril 20081 11 févr. 2006 à 02:35
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.