Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1002 connectés 

  FORUM HardWare.fr
  Programmation
  C

  optimisation

 

Sujet(s) à lire :
    - Visual C++
 

 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

optimisation

n°2255546
benreghaim​ehdi
Posté le 13-04-2015 à 08:30:38  profilanswer
 

Bonjour,
 
J'ai un petit souci, je ne sais pas comment optimiser cette fonction en C :
 
void  
baseline ( int n , double a [ n ] , double b [ n ] , double c [ n ])
{
       int i , j ;
       for ( j = 0; j < n ; j ++)
       {
                 for ( i = 0; i < n ; i ++)
                 {
                           c [ i ] += b [ n - 1 - i ];
                           if ( i < j )
                           {
                                     c [ i ] += a [ j ];
                           }
                 }
       }
}

 
En fait, je me suis renseigné, en gros il faut remonter le "if" parce qu'il coûte cher, voir pour une optimisation idéale l'éliminer (le code doit toujours rester équivalent à celui de début).
 
 
Merci pour votre aide.
 
Bonne journée.


Message édité par benreghaimehdi le 13-04-2015 à 12:37:32
mood
Publicité
Posté le 13-04-2015 à 08:30:38  profilanswer
 

n°2255547
rufo
Pas me confondre avec Lycos!
Posté le 13-04-2015 à 09:21:07  profilanswer
 

Déjà, ta fonction, elle est censée faire quoi ? Parce qu'elle a pas un poil de commentaire, les noms des variables ne sont pas explicites sur leur contenu, et t'utilises même pas la balise code :/
 
Le if dépendant de la 2ème boucle, je vois pas comment le sortir.
 
Si tu dois optimiser ce code, je commencerais par donner des noms de variables compréhensibles et j'ajouterais du commentaire. Ca n’accéléra pas le temps d'exécution, mais ça accéléra celui de sa compréhension :o


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
n°2255553
Devil'sTig​er
Posté le 13-04-2015 à 09:40:27  profilanswer
 

Remplace a l'intérieur du deuxième for par:
 

Code :
  1. if ( i < j ) {
  2.   c[i] += a[j] + b[n - 1 - i]
  3. } else {
  4.   c[i] += b[n - 1 - i]
  5. }


 
T'aura déjà un léger gain d'opti avec le += qui sera pas affecté deux fois dans le cas i < j.
 
 
Comme dit rufo sans plus d'info tu pourras pas plus optimiser sans autre information...

n°2255558
benreghaim​ehdi
Posté le 13-04-2015 à 09:53:15  profilanswer
 

Merci pour vos reponses.
 
En fait, dans un compte rendu, le prof nous demande seulement d'étudier et d'optimiser la fonction, et de justifier chaque modification du code (le code doit à la fin d'optimisation être le même que le code principal).
 
Il nous demande en fait d'optimiser la fonction, et de vérifier avec  gcc -O2 si le temps d’exécution s'améliore ou pas pour chaque optimisation de la fonction.  
 
 
Cordialement.  

n°2255562
rufo
Pas me confondre avec Lycos!
Posté le 13-04-2015 à 10:41:58  profilanswer
 

Ben, tu pourrais mettre une partie du code en ASM :whistle:


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
n°2255564
benreghaim​ehdi
Posté le 13-04-2015 à 10:48:39  profilanswer
 

Oui, c'est une solution ( code assembleur ), mais sur le compte rendu on me demande sans assembleur !

n°2255589
benreghaim​ehdi
Posté le 13-04-2015 à 12:36:12  profilanswer
 

Bonjour,
 
Je trouve des difficultés sur un travail "Optimisation en C".
Voila ce qu'il faut faire en gros :  
 
Il ya un code à optimiser, que nous appellerons "noyau".  
Il faut étuider les performances en L1, en L2, en L3 et en RAM.
 
Partie I
========
1) Ecrivez un driver permettant de mesurer la performance du noyau
2) Compilez le noyau avec gcc -O2
3) Mesurez la performance du noyau
4) Recommencez avec gcc -O3, gcc -O3 -march=native, icc -O2, icc -O3 et  
icc -O3 -xHost.
 
Partie II
=========
Pour cette partie,vous compilerez avec gcc -O2.
1) Mesurez la performance du noyau
2) Identifiez le goulet d'étranglement (ce qui limite les performances)
3) Proposez une optimisation (au niveau source)
4) Recommencez (rebouclez à l'étape 1) tant que vous arrivez à améliorer  
les performances. Vous pouvez soit repartir du noyau non optimisé, soit  
d'un noyau précédemment optimisé.
 
Partie III
==========
1) Utilisez des directives OpenMP pour paralléliser votre noyau.
2) Utilisez des intrinsics pour écrire/optimiser le code, voir modifiez directement l'assembleur.
 
 
 
J'ai réussi la partie I, mais je bloque sur la partie II et III (Optimisation du noyau)
 
voila le noyau :

Code :
  1. void kernel (int n, double a[n], double b[n], double c[n])
  2. {
  3. int i, j;
  4. for (j=0;j<n;j++)
  5. {
  6.  for(i=0;i<n;i++)
  7.  {
  8.   c[i]+=b[n-1-i];
  9.   if (i<j)
  10.   {
  11.    c[i]+=a[j];
  12.   }
  13.  }
  14. }
  15. }


 
Merci pour vos aides.
 
 
Bien cordialement.

n°2255590
gilou
Modérateur
Modzilla
Posté le 13-04-2015 à 14:04:10  profilanswer
 

Les sujets suivant ont été fusionnés à ce sujet par Gilou

  • optimisation fonction "c"


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2255596
rufo
Pas me confondre avec Lycos!
Posté le 13-04-2015 à 14:41:21  profilanswer
 

"Ecrivez un driver permettant de mesurer la performance du noyau " :ouch:  
 
Purée, c'est déjà du sacré niveau. C'est en quel cours qu'on te demande ça et dans quelle école ?


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
n°2255599
OrcusZ
Pro AMD | .Net lover
Posté le 13-04-2015 à 14:49:51  profilanswer
 

Salut,

 

Il faut chercher au niveau de la complexité algorithmique de ta fonction :
Ici la complexité de ta fonction et de N² et le plus simple pour l'optimiser et de passer ça complexité à Log(N).

 

Pour cela il faut supprimer/modifier le second "for" car c'est celui-ci qui pose problème dans la complexité.

 

Je te laisse chercher un peux avant de donné une réponse toute faire.

 

Bon courage


Message édité par OrcusZ le 13-04-2015 à 14:58:59

---------------
Made you your own sentence without believing that of the others...
mood
Publicité
Posté le 13-04-2015 à 14:49:51  profilanswer
 

n°2255602
benreghaim​ehdi
Posté le 13-04-2015 à 15:04:56  profilanswer
 

Re,
 
en fait j'ai fait ca :
 
1)  
dans un premier temps :

Code :
  1. for ( i = 0; i < n ; i++){
  2. for ( j = 0; j < n ; j++){


 
 
Cette fonction ajoute à chaque case de C son miroir dans b, n fois. Donc, déjà en une boucle je peux faire toute une partie des opérations :

Code :
  1. for (i = 0; i < n; ++i)
  2. c[ i ] += n * b[ n-1-i ];


 
 
Cela, nous donne le code suivant :

Code :
  1. for (i = 0; i < n ; i ++)
  2. {
  3. c [ i ] += n * b [ n - 1 - i ];
  4. for (j = i+1; j < n ; j ++)
  5. {
  6. c [ i ] += a [ j ];
  7. }
  8. }


 
 
Soit donc en boucle intérieure "pour  j  entre 0 et  n  et  j  supérieur à  i faire,
Donc " pour j entre i (exclus) et n ".
 

Code :
  1. for (i = 0; i < n ; i ++)
  2. {
  3. c [ i ] += n * b [ n - 1 - i ];
  4. for (j = i+1; j < n ; j ++)
  5. {
  6. c [ i ] += a [ j ];
  7. }
  8. }


 
 
Finalement, on tout du long on manipule le meme c[ i ], on peut passer par un registre temporaire :
 

Code :
  1. for ( i = 0; i < n ; i ++)
  2. {
  3. int c_temp = n * b [ n - 1 - i ];
  4. for ( j = i+1; j < n ; j ++)
  5. {
  6. c_temp += a [ j ];
  7. }
  8. c[i] += c_temp;
  9. }


 
 
mais je sais pas si c'est la meilleur optimisation.
 
Merci

n°2255604
OrcusZ
Pro AMD | .Net lover
Posté le 13-04-2015 à 15:48:33  profilanswer
 

Salut,

 

C'est l'optimisation la plus simple en tout cas.
En cherchant rapidement je suis tomber sur quasiment la même chose.

 

Tu ai bien en complexité log(N) car tu ne parcours plus deux fois ton tableau.

 

Par contre je comprends pas ton :

Code :
  1. int c_temp = n * b [ n - 1 - i ];
 

Tu n'a pas besoin de changer ce calcul ( il est imposer ).

 

Tu peux encore optimiser ta boucle en faisant du récursif mais c'est toujours un petit peu risquer ( risque de passer en overflow quelques part dans ton programme ).

 

PS : Cherche du coté des algorithmes de recherche ou de trie. Cela pourras te donner des pistes.


Message édité par OrcusZ le 13-04-2015 à 15:50:07

---------------
Made you your own sentence without believing that of the others...
n°2255610
benreghaim​ehdi
Posté le 13-04-2015 à 16:27:14  profilanswer
 

Re,
 
Franchement je ne peux pas aller plus loin que cette optimisation, par contre, m'est avis que l'ajout du a peut-être fait autrement, avec une seule boucle! En parcourant le tableau en sens inverse!  
 
J'explique  
 
j=0   rien  
j=1  
c[0]+=a[1]  
j=2  
c[0]+=a[2]  
c[1]+=a[2]  
j=3  
c[0]+=a[3]  
c[1]+=a[3]  
c[2]+=a[3]  
etc.  
 
En gros, je pense qu'il faut partir de la fin  
et puis tout mettre dans une seule boucle.
   

Code :
  1. a_cumul=j=0; 
  2. for (i=n-1;i>0;i--) { 
  3.  a_cumul+=a[i]; 
  4.  c[i]=a_cumul+n*b[j++]; 
  5. c[0]=n*b[j];

 
 
Là j'ai une seule boucle, de quoi laisser le compilo faire sa sauce pour le prefetch.
 
Quelque vous pensez ?
 
Mercii

n°2255611
OrcusZ
Pro AMD | .Net lover
Posté le 13-04-2015 à 16:38:07  profilanswer
 

ça à l'air cohérent.
 
Si lorsque tu trace tu obtient toujours le même résultat ( entre ton algo et celui de base ) tu es passé à une complexité de N.
 
Donc tu ne pourra pas faire mieux.
 
Bravo :)


---------------
Made you your own sentence without believing that of the others...

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  optimisation

 

Sujets relatifs
Incrementer en fonction de l'annéeCharger dynamiquement une fonction avec greasmonkey
Créer une fonction acceptant divers arguments en CVBA - optimisation de portefeuille
bouton de redirection en fonction du loginFonction compatible php 5.5.12 mais non-compatible php 5.3.3 pq?
Matlab : Faire une fonction avec des matrices plutôt qu'une boucle forOptimisation d'une fonction img 2D
Défi: optimisation d'une fonction de convertion (Bin => Dec)fonction html : listbox optimisation?
Plus de sujets relatifs à : optimisation


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR