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

Visual C++ Discussion :

optimisation : à ne plus rien y comprendre !


Sujet :

Visual C++

  1. #1
    Membre éclairé
    Inscrit en
    Juillet 2006
    Messages
    75
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 75
    Par défaut optimisation : à ne plus rien y comprendre !
    Observez bien les 2 fonctions ci-dessous : elles sont identiques, sauf les 2 lignes en rouge qui ne sont pas au même endroit. J'ai laisser volontairement "le gras" autour car certains y trouver peut-être (j'espère !) une réponse à mes interrogations.

    (Pour les amateurs d'imagerie il s'agit de la méthode de seuillage dite de Kohler)

    fonction 1 :
    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
            unsigned char s; 
    	int i,j,k,n,m,p,q;
    	unsigned char voisinage[4];
    	unsigned char pixel;
    	double card, contraste;
    	double Cmoy=0.0;
    	unsigned char so=0;
    
    	for (s=s_min; s<=s_max; s++)
    	{
    		contraste=0.0;
    		card=0.0;
    
    		for (i=1; i<nblig-1; i++)
    		{
    			n=i*tlig;
    
    			p=(i-1)*tlig;
    			q=(i+1)*tlig;
    
    			for(j=1; j<nbcol-1; j++)
    			{
    				m=n+j;
    				pixel = bits[m];	//pixel courant
    
    				// voisinage V4
    				voisinage[0] = bits[p+j];
    				voisinage[1] = bits[q+j];
    				voisinage[2] = bits[m-1];
    				voisinage[3] = bits[m+1];
    			
    				for (k=0;k<4;k++)
    				{
    					if ( valmin(pixel,voisinage[k])<=s && valmax(pixel,voisinage[k])>s )
    					{
    						card++;
    						contraste+=valmin(abs(s-voisinage[k]),abs(s-pixel));
    					}
    				}
    			}
    		}
    
    		if (card>0.1) 
    		{
    			contraste*=(1/card);
    			if (contraste>Cmoy)
    			{
    				Cmoy = contraste;
    				so = s;
    			}
    		}
    	}
    fonction 2 :
    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
            unsigned char s; 
    	int i,j,k,n,m,p,q;
    	unsigned char voisinage[4];
    	unsigned char pixel;
    	double card, contraste;
    	double Cmoy=0.0;
    	unsigned char so=0;
    
    	for (s=s_min; s<=s_max; s++)
    	{
    		contraste=0.0;
    		card=0.0;
    
    		for (i=1; i<nblig-1; i++)
    		{
    			n=i*tlig;
    
    			for(j=1; j<nbcol-1; j++)
    			{
    				m=n+j;
    				pixel = bits[m];	//pixel courant
    
                                    p=(i-1)*tlig;
    			        q=(i+1)*tlig;
    
    				// voisinage V4
    				voisinage[0] = bits[p+j];
    				voisinage[1] = bits[q+j];
    				voisinage[2] = bits[m-1];
    				voisinage[3] = bits[m+1];
    			
    				for (k=0;k<4;k++)
    				{
    					if ( valmin(pixel,voisinage[k])<=s && valmax(pixel,voisinage[k])>s )
    					{
    						card++;
    						contraste+=valmin(abs(s-voisinage[k]),abs(s-pixel));
    					}
    				}
    			}
    		}
    
    		if (card>0.1) 
    		{
    			contraste*=(1/card);
    			if (contraste>Cmoy)
    			{
    				Cmoy = contraste;
    				so = s;
    			}
    		}
    	}
    Suivant toute logique, la 1ère version est plus rapide, les lignes déplacées ne faisant intervenir que des termes en i. Et c'est là que le bas blaisse : en réalité il n'en est rien. Suivant les mesures que j'ai pu faire :

    l'exécution de la fonction 1 (à priori plus rapide) : 320ms
    l'exécution de la fonction 2 (à priori plus lente) : 300ms

    Les mesures sont faites sous un processus avec une priorité "temps réel" et en exécutant plusieurs fois la même fonction (moyennage). Je tiens également à préciser que ces temps d'exécution sont très très répétables dans le temps.

    Que ce passe-t-il donc ?

    Autre fait intérressant, si je passe le mode d'optimisation de Visual C++ 6.0 de "Maximize speed" (réglage par défaut) à "Default" (pas d'optimisation) je me retrouve avec un temps d'exécution de l'ordre de 900ms mais la fonction 1 est cette fois ci plus rapide.

    Serait-ce le compilo qui pête les plombs ?

    Si quelqu'un vois quelque que chose qui m'échappe là dedans et qui pourrait me permettre de comprendre pourquoi un code moins bien tapé et entrainant l'éxécution de plus d'instructions est exécuté plus rapidement merci de me faire signe !

  2. #2
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 526
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 526
    Par défaut
    Il y a quelque chose que je ne comprends pas : p et q dans la fonction 2 sont affectés ( et donc modifiés ) plus de fois que dans la fonction 1 donc les traitements et résultats doivent être différents ? Ou je me trompe ?
    Et c'est là que le bas blaisse
    -> Et c'est là que le bat blesse ( bat avec accent circonflexe je ne peux pas le reproduire )

  3. #3
    Membre éclairé
    Inscrit en
    Juillet 2006
    Messages
    75
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 75
    Par défaut
    oulala !!! pardon pour cette grossière faute c'est pourtant pas mon genre

    p et q ne sont fonction que de i uniquement, dans la boucle j ils sont donc réafectés inutilement puisqu'ils conservent la même valeur. Les résultats sont donc les mêmes avec les 2 fonctions.

  4. #4
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 526
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 526
    Par défaut
    ceci dit cela n'explique pas la différence en ms ..

  5. #5
    Membre éclairé
    Inscrit en
    Juillet 2006
    Messages
    75
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 75
    Par défaut
    toujours pas d'idées ?

  6. #6
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 526
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 526
    Par défaut
    La différence peut s'expliquer que dans le code assembleur les variables soient placées sur la pile avec des PUSH et des POP.
    Si tu connais l'assembleur i386 cela pourra t'éclairer de comprendre le code généré.
    Il n'y a que cette démarche qui puisse apporter l'explication

Discussions similaires

  1. Boucle qui foire,a n'y plus rien comprendre
    Par pridzi dans le forum Programmation multimédia/Jeux
    Réponses: 7
    Dernier message: 20/11/2009, 17h54
  2. Je n'y comprend plus rien
    Par Pingouinvert dans le forum Décisions SGBD
    Réponses: 4
    Dernier message: 11/09/2005, 10h57
  3. [BDE] Plus rien dans Configuration/Drivers/Native
    Par Harry dans le forum Bases de données
    Réponses: 5
    Dernier message: 11/02/2005, 16h15
  4. Root qui ne peux plus rien faire :'(
    Par Smortex dans le forum Administration
    Réponses: 2
    Dernier message: 27/09/2004, 20h13
  5. [Kylix] Je n'y comprends plus rien
    Par fafamonteko dans le forum EDI
    Réponses: 5
    Dernier message: 02/03/2004, 16h48

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