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

C++ Discussion :

Probl�me de lenteur avec un vecteur de vecteur


Sujet :

C++

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre chevronn�

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    426
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de D�me (Auvergne)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 426
    Par d�faut Probl�me de lenteur avec un vecteur de vecteur
    Salut � tous,

    J'ai r�cemment cr�� un classe ( en natif ) dont l'un des membres donn�e est un tableau 2d du type vector<vector<double> >. L'une des fonction membre fais l'addition membre � membre de trois de ces tableaux et l� : c'est horriblement lent!

    Dans mes essais, le tableau fais environ 500*400, et le traitement de celui-ci prend facilement0,2 � 0,3 secondes!!. Et il faut r�it�rer le calcul des centaines et des milliers de fois! ( C'est une simulation de diffusion osmotique en milieux 2d, pour chaque 'pixel' on d�termine quelle quantit� de 'produit' est ( ou pas ) transf�r�e aux 'pixels' voisins )

    Puisque le PC sur lequel je fais tourner ce code est capable de faire tourner un simulateur de vol en temps r�el, j'imagine que le probl�me ne vient pas du PC mais du programmeur!

    Quels sont les "trucs et astuces" pour pouvoir demander au PC de traiter plus rapidement une partie du code. J'ai lu sur certains posts des histoires de "cache" : un d�velopper de jeux disait qu'il faut savoir l'utiliser pour que �a tourne vite, mais �a d�passe mes connaissances. Pouvez-vous me mettre sur la ou les bonnes pistes?

    PS : Le PC en question est monoprocesseur, inutile donc de me parler de parall�lisation

  2. #2
    screetch
    Invit�(e)
    Par d�faut
    un vecteur de vecteur est horriblement lent.
    montre le code qui fait l'addition pour avoir plus d'id�es.
    Dans vector il y a une fonction "resize" qui pourrait t'aider aussi:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    vector<vector<double> > result;
    result.resize(input.size());
    for(int i = 0; i < input1.size(); ++i)
    {
      result[i].resize(input[i].size());
      for(int j = 0; j < input[i].size(); ++j)
      {
        result[i][j] = input[i][j] + input2[i][j];
      }
    }
    c'est deja un d�but.

  3. #3
    Membre chevronn�

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    426
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de D�me (Auvergne)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 426
    Par d�faut
    un vecteur de vecteur est horriblement lent
    Alors que puis-je utiliser � la place d'un vecteur de vecteur?
    Pourquoi 'resize'?

    Ca fait plusieurs jours que je met au point et que j'optimise mon code ( ce morceau n'en est qu'une partie ). Mais j'ai commis une grosse erreur de d�butant : c'est de ne pas faire un template d�s le d�but ! Je me rends compte en testant mon programme que je n'ai pas forc�ment besoin de la pr�cision d'un double. Je r��cris actuellement ma class sous forme de template

    Voici des extraits : la d�claration de mon class template et la d�finition de la fonction Diffuse:
    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
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
     
    template <typename T, typename U> class Terrain
    {
    protected:
    	unsigned int Width;
    	unsigned int Height;
    	std::vector<std::vector<T> > Sol;
    	T CoefficientDeDiffusion;
    	T CoefficientDEvaporation;
    public:
    	Terrain ( const unsigned int l, const unsigned int h );
    	Terrain ( const Terrain<T,U>& ter );
    	~Terrain ();
    	Terrain<T,U>& operator = ( Terrain<T,U> &ter );
     
    	void affiche () const;
     
    	void SetSol ( const unsigned int l, const unsigned int h, T valeur );
    	void SetCoefficientDeDiffusion ( T coeffDiff );
    	void SetCoefficientDEvaporation ( T coeffEvap );
     
    	void Diffuse ( U dT );
    };
     
    template <typename T, typename U> void Terrain<T,U>::Diffuse ( U dT )
    {
    	std::vector<std::vector<T> > flux;
    	std::vector<std::vector<T> > pertes;
    	T courant;			//Valeur du pixel courant
    	T vh, vb, vg, vd;	//Valeurs des pixels voisins
    	T p, pTempo;			//Variables auxiliaires
    	const T zero = static_cast<T>( 0 );
     
    	//flux et pertes sont initialisée pour faire sx de large et sy de haut
    	for ( unsigned int y = 0; y < Height; y++ )
    	{
    		flux.push_back ( std::vector<T> ( Width,  zero ) );
    		pertes.push_back ( std::vector<T> ( Width,  zero ) );
    	}
     
    	//Calcule de diffusion
    	for ( unsigned int y = 0; y < Height; ++y )
    	{
    		for ( unsigned int x = 0; x < Width; ++x )
    		{
    			vh = zero;	vb = zero;	vg = zero;	vd = zero;	p = zero;
    			courant = Sol[y][x];
     
    			//Calcul de flux : ce que gagne chaques pixels voisins
    			if ( y )			//Si on est pas à la première ligne
    			{
    				vh = Sol[y-1][x];
    				if ( courant > vh )
    				{
    					pTempo = dT * CoefficientDeDiffusion * ( courant - vh );
    					flux[y-1][x] = pTempo;
    					p += pTempo;
    				}
    			}
    			if ( y < Height-1 )	//Si on est pas à la dernière ligne
    			{
    				vb = Sol[y+1][x];
    				if ( courant > vb )
    				{
    					pTempo = dT * CoefficientDeDiffusion * ( courant - vb );
    					flux[y+1][x] = pTempo;
    					p += pTempo;
    				}
    			}
    			if ( x )			//Si on est pas à la première colonne
    			{
    				vg = Sol[y][x-1];
    				if ( courant > vg )
    				{
    					pTempo = dT * CoefficientDeDiffusion * ( courant - vg );
    					flux[y][x-1] = pTempo;
    					p += pTempo;
    				}
    			}
    			if ( x < Width-1 )	//Si on est pas à la dernière colonne
    			{
    				vd = Sol[y][x+1];
    				if ( courant > vd )
    				{
    					pTempo = dT * CoefficientDeDiffusion * ( courant - vd );
    					flux[y][x+1] = pTempo;
    					p += pTempo;
    				}
    			}
     
    			//Calcul de pertes : ce que perd ce pixel
    			pertes[y][x] = p + dT * CoefficientDEvaporation;
    		}
    	}
     
    	//Calcul final : On additionne au tableau d'origine le tableau des flux
    	//				et on y soustrait celui des pertes
    	for ( unsigned int y = 0; y < Height; ++y )
    		for ( unsigned int x = 0; x < Width; ++x )
    			Sol[y][x] += flux[y][x] - pertes[y][x];
    }

  4. #4
    Membre �m�rite
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Mars 2011
    Messages
    618
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 618
    Par d�faut
    Salut,

    Premi�re chose, d�brouille toi pour organiser tes donn�es de mani�re � ce qu'elles soit � la suite dans la m�moire. Par exemple, n'utilise qu'un seul tableau comme ceci:

    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
     
    int largeur = 500;
    int hauteur = 800;
    std::vector<double> tableau(largeur*hauteur);
    // acceder a la valeur (i, j):
    tableau[j * largeur + i];
     
    // parcourir tous les points:
    // Attention, la boucle du i doit être à l'interieur, de manière a ce que
    // lorsque tu parcour ton tableau, tu ne fasse pas de "saut" dans la mémoire
    for ( int j = 0; j < hauteur; ++j )
    {
      for ( int i = 0; i < largeur; ++i )
      {
         tableau[j * largeur + i];
      }
    }
    C'est moins claire, mais diablement plus rapide

  5. #5
    screetch
    Invit�(e)
    Par d�faut
    dans ton code:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    	for ( unsigned int y = 0; y < Height; y++ )
    	{
    		flux.push_back ( std::vector<T> ( Width,  zero ) );
    		pertes.push_back ( std::vector<T> ( Width,  zero ) );
    	}
    je parie c'est ca qui est lent
    push_back peut r�allouer le vector
    en r�allouant le vector il doit recopier tous les vector qu'il contient
    c'est exactement pour ca que vector<vector> c'est nul niveau perfs
    resize visait justement a �viter ca.

    la diff�rence entre float et double se fera peut etre meme pas sentir... la regle si on veut am�liorer les perfs est de voir ou l'on passe du temps.
    si tu ne sais pas ce qu'est un profiler:
    * soit c'est le bon moment pour apprendre
    * soit tu mets des timer dans ton code pour calculer combien de temps prennent les op�rations

    sinon tu optimises a l'aveugle et ca c'est un peu naze

  6. #6
    Membre chevronn�

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    426
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de D�me (Auvergne)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 426
    Par d�faut
    Merci pour les r�ponses screetch et pyros

    @Pyros : Je vais tester cette fa�on de proc�der en tenant bien compte du fait que
    la boucle du i doit �tre � l'interieur, de mani�re a ce que lorsque tu parcour ton tableau, tu ne fasse pas de "saut" dans la m�moire
    , �a permettra de virer les "push_back ( std::vector<T> ( Width, zero )" sur lesquels Screetch attire mon attention

    @Screetch : En effet, je ne connais pas les "profilers" ( C'est le probl�me quand on est autodidacte dans un domaine, on ne connais que ce dont on a eu besoin ( moi je suis ing�nieur en m�canique � la base, et il y a 15 ans dans mon �cole, la formation en informatique �tait assez limit�e : quelques heures de pascal tout au plus!!! ) ). Je vais tester la m�thode des timers, et regarder ce qu'est un "profiler" d�s que j'en ai le temps.

    Merci encore � vous deux, donc.

    Je coche ce post comme r�solu, mais si quelqu'un a d'autres piste, qu'il n'h�site pas.

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. R�ponses: 5
    Dernier message: 18/05/2010, 18h12
  2. [WD11][E-07]Probl�me de lenteur avec le driver odbc
    Par law56100 dans le forum HyperFileSQL
    R�ponses: 0
    Dernier message: 26/05/2009, 17h50
  3. R�ponses: 2
    Dernier message: 08/11/2007, 14h07
  4. probl�me de lenteur avec BO
    Par darwini dans le forum D�buter
    R�ponses: 2
    Dernier message: 13/04/2007, 14h08
  5. Probl�me de lenteur avec 2 sous-formulaires
    Par picatchou dans le forum Access
    R�ponses: 1
    Dernier message: 29/01/2007, 08h48

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