[C] Problème de macro

Problème de macro [C] - Programmation

Marsh Posté le 05-07-2002 à 13:46:45    

Salut,
 
J'ai 1 fonction qui marche très bien et j'ai voulu en faire une macro. Mais sous forme de macro, ça ne marche plus. Je voia aucune différence entre les 2 :
 
 

Code :
  1. //La fonction :
  2. Uint8  getpixel8(SDL_Surface *surface, int x, int y) {
  3. return ((Uint8 *)surface->pixels)[x + y * surface->w];
  4. }
  5. //La macro :
  6. #define GETPIXEL8(surface, x ,y) ((Uint8 *)surface->pixels)[x + y * surface->w]

Reply

Marsh Posté le 05-07-2002 à 13:46:45   

Reply

Marsh Posté le 05-07-2002 à 15:33:24    

Bon j'ai trouvé, c'était 1 manque de () autour du x et du y (pb classque avec les macros)
 
 

tomiotomio a écrit a écrit :

 
par ailleurs, je vois pas bien  l interet d en faire une maccro




 
Ben pour éviter un appel de f°

Reply

Marsh Posté le 05-07-2002 à 15:42:55    

bobdupont a écrit a écrit :

Bon j'ai trouvé, c'était 1 manque de () autour du x et du y (pb classque avec les macros)
 
 
Ben pour éviter un appel de f°




 
??? Mouais


---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
Reply

Marsh Posté le 05-07-2002 à 15:43:57    

Rajoute un groupe de parenthés autour, marchera peut être mieu


---------------
Le Tyran
Reply

Marsh Posté le 05-07-2002 à 16:10:09    

bobdupont a écrit a écrit :

 
Ben pour éviter un appel de f°




Ce genre d'optimisation était valable à l'époque des 8086... mais de nos jours ??  :sarcastic:  
 
De plus, si vraiment tu tiens à ne pas faire d'appel de fonction, tu peux toujours déclarer cette fonction inline...


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 05-07-2002 à 16:13:15    

Harkonnen a écrit a écrit :

 
Ce genre d'optimisation était valable à l'époque des 8086... mais de nos jours ??  :sarcastic:  




 
C'est une fonction pour lire 1 pixel dans la mémoire video
+ c'est rapide mieux c'est
 

Harkonnen a écrit a écrit :

 
De plus, si vraiment tu tiens à ne pas faire d'appel de fonction, tu peux toujours déclarer cette fonction inline...




 
Il s'agit d'un source C

Reply

Marsh Posté le 05-07-2002 à 17:36:26    

bobdupont a écrit a écrit :

Il s'agit d'un source C


inline existe en C99.


---------------
« No question is too silly to ask, but, of course, some are too silly to answer. » -- Perl book
Reply

Marsh Posté le 05-07-2002 à 18:03:14    

effectivement, il faut probablement rajouter une parenthèse.
 
pour la vitesse oui un "call" (appel de sous-fonction) par pixel dans une routine travaillant au niveau pixel réduirait dramatiquement les performances, même sur un cpu actuel (ni les CPU ni les optimisations de carte 3D ne compensent des erreurs de programmation)
 
ensuite la pluspart des compilateurs C ou C++ font de l'expansion en ligne automatique, donc si tu mets toutes les options d'optimisations et ça devrait aller (au pire tu contrôles le code généré en assembleur). Même pas forcément besoin d'un inline.
 
ensuite si tu veux booster y'a une méthode plus simple pour gagner du temps:
 
unsigned char *Buffer=surface->pixels;
 
et tu te balades avec un Buffer[....]
 
ensuite vu que tu risques de faire des for, je te conseilles une approche type:
 

Code :
  1. unsigned char *Buffer=surface->pixels;
  2. int i=hauteur;
  3. do {
  4.   int j=largeur;
  5.   unsigned char *Ptr=Buffer; // ligne courante
  6.   // traitement pixel par pixel
  7.   do {
  8.      *Ptr=traitement(*Ptr);
  9.      Ptr++;
  10.   } while(--j);
  11.   Buffer+=largeur; // ligne suivante
  12. } while(--i);


 
1) effectivement éviter les "call", si le compilo fait de l'expension en ligne, pas de problème....
 
2) remonter tout ce qui est constant dans la boucle la plus imbriqué pour refaire monter le calcul des constantes dans les boucles supérieures... (par exemple remonter des calculs de constante propres à chaque ligne dans le while() des lignes)
 
3) éviter les calcul d'adresse par des multiplications genre [y*largeur+x], favoriser des incrémentations/addition de pointeurs....
 
4) tables de précalcul...
 
pour gagner du temps il ne faut pas chercher à avoir un foncion putpixel/getpixel rapide, mais à avoir la routine qui traite un bloc de pixel relativement bien optimisée)
Pour booster, il faut pas penser un routine qui traite un élément, mais une routine qui traite un "tableau" d'éléments....


Message édité par bjone le 05-07-2002 à 18:06:20
Reply

Marsh Posté le 05-07-2002 à 18:05:24    

bjone a écrit a écrit :

ensuite la pluspart des compilateurs C ou C++ font de l'expansion en ligne automatique, donc si tu mets toutes les options d'optimisations et ça devrait aller (au pire tu contrôles le code généré en assembleur). Même pas forcément besoin d'un inline.


De toute façon, inline, c'est comme register : la norme précise bien que ce n'est qu'une indication d'optimisation qui n'a rien d'impératif.


---------------
« No question is too silly to ask, but, of course, some are too silly to answer. » -- Perl book
Reply

Marsh Posté le 05-07-2002 à 18:10:43    

l'inline est pas génant.
 
le "register" peut être une contre-optimisation.
 
un bon compilo avec toutes les options d'optimisations saura relativement très bien allouer les registres aux varibles, et le fait de forcer une variable dans un registre pourrait s'avérer être une contre-optimisation, par exemple:
 
ça comme ça, c'est pas forcément mauvais:
 

Code :
  1. unsigned char *Buffer=surface->pixels;
  2. int i=hauteur;
  3. do {
  4. register int j=largeur;
  5. register unsigned char *Ptr=Buffer; // ligne courante  
  6. // traitement pixel par pixel  
  7. do {
  8.     *Ptr=traitement(*Ptr);
  9.     // d'autres register pour le traitement()
  10.     Ptr++;
  11. } while(--j);
  12. Buffer+=largeur; // ligne suivante  
  13. } while(--i);

 
 
et ça c'est plustôt pas bon si la boucle pixel par pixel n'a plus de registre:
 

Code :
  1. register unsigned char *Buffer=surface->pixels;
  2. register int i=hauteur;
  3. do {
  4. int j=largeur;
  5. unsigned char *Ptr=Buffer; // ligne courante  
  6. // traitement pixel par pixel  
  7. do {
  8.     *Ptr=traitement(*Ptr);
  9.     Ptr++;
  10. } while(--j);
  11. Buffer+=largeur; // ligne suivante  
  12. } while(--i);

 
 
 
la règle d'or c'est de toujours favoriser la boucle la plus imbriqué pour gagner du temps, il faut favoriser le code qui a la plus haute fréquence d'éxécution...


Message édité par bjone le 05-07-2002 à 18:11:25
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed