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 :

[Performance] Image RGB et GrayScale


Sujet :

C++

  1. #21
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par poukill Voir le message
    Mais tout de même, pourquoi cette performance nulle en float? Mise en cache pas suffisante???
    EN faite y as un petit problème dans mon code... Lors de la multiplication fait num fois, y as de forte chance que tout les float devienne infinie et les type entier à zéro. Et le cas des inf est un cas particulier qui il me semble plomb les résultats....
    Il faudrait régénérer les pixels de l'image avant chaque traitement...

  2. #22
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Voila
    je ne pense pas m'être trompé.
    J'ai par contre viré le std::numeric_limits<T>::max() car avec les float tu as trés souvent un inf aprés la multiplication.

    Si je ne me suis pas gouré, ça devrait fortement te rassurer (multiplication parfois plus rapide en rgb )
    Par contre l'écart n'est pas constant, mais j'ai une machine de merde au taf
    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
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    #include <iostream>
    #include <vector>
    #include <list>
    #include <deque>
    #include <set>
    #include <algorithm>
    #include <ctime>
    #include <cmath>
    #include <limits>
    using namespace std;
    const int num =1000;
     
    template<typename T>
    struct Image
    {
    	typedef T value_type;
     
        Image(int hh,int ww)
        :h(hh),w(ww),buffer(hh*ww)
        {}
        int h;
        int w;
        vector<T> buffer;
    };
     
    template <typename T>
    struct RGB
    {
        RGB():r(0),g(0),b(0)
        {};
     
        RGB(T rr,T gg,T bb)
        :r(rr),g(gg),b(bb)
    	{}
     
        T r;
        T g;
        T b;
     
    	template <typename TYPE>
        RGB& operator*=(TYPE a)
        {
            r*=a;
            g*=a;
            b*=a;
            return *this;
        }
    };
     
    template <typename T>
    struct Gen
    {
    	T operator()()
        {
    		return static_cast<T> ((rand() * 1.0)/RAND_MAX * 1024 ) ;
        }
    };
     
    template <typename T>
    struct GenRGB
    {
        RGB<T> operator()()
        {
            RGB<T> p;
    		p.r = static_cast<T> ((rand() * 1.0)/RAND_MAX * 1024) ;
            p.g = static_cast<T> ((rand() * 1.0)/RAND_MAX * 1024 ) ;
    		p.b = static_cast<T> ((rand() * 1.0)/RAND_MAX * 1024 ) ;
            return p;
        }
     
    };
    template <typename T>
    struct Multiplie
    {
        Multiplie(T aa):a(aa){};
     
    	template <typename TYPE>
        void operator()(TYPE & RGB)
        {
            RGB *= a;
        }
        T a;
    };
     
     
    template <typename T>
    struct MIN
    {
    	typedef T value_type;
     
        MIN():min(255){};
        void operator()(T RGB)
        {
            if (RGB<min) min = RGB;
        }
        T min;
    };
     
    template <typename T>
    struct MINRGB
    {
        MINRGB()
        :min(255,255,255)
        {}
        void operator()(const RGB<T> & RGB)
        {
            if (RGB.r<min.r) min.r = RGB.r;
            if (RGB.g<min.g) min.g = RGB.g;
            if (RGB.b<min.b) min.b = RGB.b;
        }
        RGB<T> min;
    };
     
     
     
     
    int main(int argc, unsigned char* argv[])
    {	
    	typedef unsigned short  TYPE_GRAYSCALE;
    	typedef float			TYPE_RGB;
     
     
    	// GENERATION DES IMAGES ...
    	srand(clock());
        Image<TYPE_GRAYSCALE> img(256,256);
    	Image<RGB<TYPE_RGB>>  imgRGB(256,256);
     
     
    	// FIN GENERATION
     
     
        while(1)
        {
     
    	    clock_t tSomme(0);
    		for (int i =0;i<num;++i)
    		{
     
    	        std::generate
    	        (
    		    img.buffer.begin(),
    		    img.buffer.end(),
    		    Gen<TYPE_GRAYSCALE>()
    	        );
     
                clock_t t0 = clock();
    			std::for_each
    				(
    					img.buffer.begin(),
    					img.buffer.end(),
    					Multiplie<double>(3.5)
    				 );
                tSomme+=clock()-t0;
    		}
    		double tempA = double(tSomme)/num;
    		std::cout<<"************MULTIPLICATION**************" <<std::endl;
    		std::cout<<"grayscale""  "<<tempA <<std::endl;
     
            tSomme =0;
    		for (int i =0;i<num;++i)
    		{
     
    	    std::generate
    	       (
    		       imgRGB.buffer.begin(),
    		       imgRGB.buffer.end(),
    		       GenRGB<TYPE_RGB>()
    	       );
             clock_t t0 = clock();
    			std::for_each
    				(
    					imgRGB.buffer.begin(),
    					imgRGB.buffer.end(),
    					Multiplie<double>(3.5)
    				 );
             tSomme+=clock()-t0;
    		}
    		double tempB = double(tSomme)/num;
    		std::cout<<"rgb"<<"  "<<tempB <<std::endl;
     
    		std::cout<<"rgb/grayscale"<<" "<<100*(tempB/tempA)<<"%"<<std::endl;
     
            tSomme =0;
    		int min;
    		for (int i =0;i<num;++i)
    		{
    	        std::generate
    	        (
    		    img.buffer.begin(),
    		    img.buffer.end(),
    		    Gen<TYPE_GRAYSCALE>()
    	        );
     
                clock_t t0 = clock();
    			min = std::for_each
    				(
    					img.buffer.begin(),
    					img.buffer.end(),
    					MIN<TYPE_GRAYSCALE>()
    				 ).min;
                tSomme+=clock()-t0;
    		}
    		tempA = double(tSomme)/num;
    		std::cout<<"************MIN**************" <<std::endl;
    		std::cout<<"grayscale""  "<<tempA <<std::endl;
     
    		tSomme =0;
    		RGB<TYPE_RGB> minRGB;
    		for (int i =0;i<num;++i)
    		{
    	    std::generate
    	       (
    		       imgRGB.buffer.begin(),
    		       imgRGB.buffer.end(),
    		       GenRGB<TYPE_RGB>()
    	       );
               clock_t t0 = clock();
    		   minRGB = std::for_each
    				(
    					imgRGB.buffer.begin(),
    					imgRGB.buffer.end(),
    					MINRGB<TYPE_RGB>()
    				 ).min;
               tSomme+=clock()-t0;
    		}
    		tempB = double(tSomme)/num;
    		std::cout<<"rgb "<<minRGB.r<<"  "<<minRGB.g<<"  "<<minRGB.b<<"  "<<tempB <<std::endl;
     
    		std::cout<<"B/A"<<" "<<100*(tempB/tempA)<<"%"<<std::endl;
        }
     
    	return 0;
    }
    edit sur le code.
    Tu t'était planté sur les parametre de Multiplie... d'ailleur je ne comprend pas comment il as pu convertir un double en RGB

  3. #23
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    petite astuce sous visual pour gagné en rgb sur le min. Tu vire la récupération du min. Tu aura un temp = 0 il est trop fort le compilo, il as vue que l'on ne faisait rien et il as virée le foreach

  4. #24
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Citation Envoyé par Mongaulois Voir le message
    Tu t'était planté sur les parametre de Multiplie... d'ailleur je ne comprend pas comment il as pu convertir un double en RGB
    ??? il a jamais eu besoin de convertir en RGB ! le multiplie prend en paremetre un float ou bien un entier... Et la structure RGB a deja un operateur pour multiplier par quelquechose...
    pas de souci non???

  5. #25
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par poukill Voir le message
    ??? il a jamais eu besoin de convertir en RGB ! le multiplie prend en paremetre un float ou bien un entier... Et la structure RGB a deja un operateur pour multiplier par quelquechose...
    pas de souci non???
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    template <typename T>
    struct Multiplie
    {
        Multiplie(T aa):a(aa){};
     
    	template <typename TYPE>
        void operator()(TYPE & RGB)
        {
            RGB *= a;
        }
        T a;
    };
     
    Multiplie<TYPE_RGB>(2)
    donc a et aa sont des RGB et donc tu initialise aa avec 2

    [edit]
    j'ai dit n'importe quoi... j'ai confondu RGB et TYPE_RGB

  6. #26
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Non a et aa sont des ENTIERS !
    Dans le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    std::for_each ( img.buffer.begin(), img.buffer.end(),  Multiplie<TYPE_RGB>(2) );
    a et aa seront de TYPE_RGB donc des float dans mon exemple...

    Et multiplier par un foat, ma structure RGB sait faire !!!


    EDIT : OK no pb mon code etait peut etre pas super clair...

  7. #27
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Si il n'y as pas d'erreur,en gros,
    je gagne en moyenne 50% avec rgb par rapport au grayscale.
    Comme quoi.


    Pour le min, c'est un peu n'importe quoi comme bench... Il faudrait que pour chaque iteration que les trois plan RGB soi identique à l'image greayscale pour la même iteration. Il recherche ainsi la même chose au même endroit.

  8. #28
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Re,

    Si, il y a erreur...
    Ton Multiplie prend en parametre template toujours un double, ce qui penalise bcp le GreyScale !
    En mettant bien unsigned short dans les deux, on gagne un facteur 15...
    Et on retrouve bien le greyscale plus rapide et le RGB plus lent avec 200 a 300 % en moyenne...

    Code mis a jour :
    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
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
     
    #include <iostream>
    #include <vector>
    #include <list>
    #include <deque>
    #include <set>
    #include <algorithm>
    #include <ctime>
    #include <cmath>
    #include <limits>
    using namespace std;
    const int num =1000;
     
    template<typename T>
    struct Image
    {
    	typedef T value_type;
     
        Image(int hh,int ww)
        :h(hh),w(ww),buffer(hh*ww)
        {}
        int h;
        int w;
        vector<T> buffer;
    };
     
    template <typename T>
    struct RGB
    {
        RGB():r(0),g(0),b(0)
        {};
     
        RGB(T rr,T gg,T bb)
        :r(rr),g(gg),b(bb)
    	{}
     
        T r;
        T g;
        T b;
     
    	template <typename TYPE>
        RGB& operator*=(TYPE a)
        {
            r*=a;
            g*=a;
            b*=a;
            return *this;
        }
    };
     
    template <typename T>
    struct Gen
    {
    	T operator()()
        {
    		return static_cast<T> ((rand() * 1.0)/RAND_MAX * 1024 ) ;
        }
    };
     
    template <typename T>
    struct GenRGB
    {
        RGB<T> operator()()
        {
            RGB<T> p;
    		p.r = static_cast<T> ((rand() * 1.0)/RAND_MAX * 1024) ;
            p.g = static_cast<T> ((rand() * 1.0)/RAND_MAX * 1024 ) ;
    		p.b = static_cast<T> ((rand() * 1.0)/RAND_MAX * 1024 ) ;
            return p;
        }
     
    };
    template <typename T>
    struct Multiplie
    {
        Multiplie(T aa):a(aa){};
     
    	template <typename TYPE>
        void operator()(TYPE & RGB)
        {
            RGB *= a;
        }
        T a;
    };
     
     
    template <typename T>
    struct MIN
    {
    	typedef T value_type;
     
        MIN():min(255){};
        void operator()(T RGB)
        {
            if (RGB<min) min = RGB;
        }
        T min;
    };
     
    template <typename T>
    struct MINRGB
    {
        MINRGB()
        :min(255,255,255)
        {}
        void operator()(const RGB<T> & RGB)
        {
            if (RGB.r<min.r) min.r = RGB.r;
            if (RGB.g<min.g) min.g = RGB.g;
            if (RGB.b<min.b) min.b = RGB.b;
        }
        RGB<T> min;
    };
     
     
     
     
    int main(int argc, unsigned char* argv[])
    {	
    	typedef unsigned short  TYPE_GRAYSCALE;
    	typedef float			TYPE_RGB;
     
     
    	// GENERATION DES IMAGES ...
    	srand(clock());
        Image<TYPE_GRAYSCALE> img(256,256);
    	Image<RGB<TYPE_RGB>>  imgRGB(256,256);
     
     
    	// FIN GENERATION
     
     
        while(1)
        {
     
    	    clock_t tSomme(0);
    		for (int i =0;i<num;++i)
    		{
     
    	        std::generate
    	        (
    		    img.buffer.begin(),
    		    img.buffer.end(),
    		    Gen<TYPE_GRAYSCALE>()
    	        );
     
                clock_t t0 = clock();
    			std::for_each
    				(
    					img.buffer.begin(),
    					img.buffer.end(),
    					Multiplie<TYPE_GRAYSCALE>(3.5)
    				 );
                tSomme+=clock()-t0;
    		}
    		double tempA = double(tSomme)/num;
    		std::cout<<"************MULTIPLICATION**************" <<std::endl;
    		std::cout<<"grayscale""  "<<tempA <<std::endl;
     
            tSomme =0;
    		for (int i =0;i<num;++i)
    		{
     
    	    std::generate
    	       (
    		       imgRGB.buffer.begin(),
    		       imgRGB.buffer.end(),
    		       GenRGB<TYPE_RGB>()
    	       );
             clock_t t0 = clock();
    			std::for_each
    				(
    					imgRGB.buffer.begin(),
    					imgRGB.buffer.end(),
    					Multiplie<TYPE_RGB>(3.5)
    				 );
             tSomme+=clock()-t0;
    		}
    		double tempB = double(tSomme)/num;
    		std::cout<<"rgb"<<"  "<<tempB <<std::endl;
     
    		std::cout<<"rgb/grayscale"<<" "<<100*(tempB/tempA)<<"%"<<std::endl;
     
            tSomme =0;
    		int min;
    		for (int i =0;i<num;++i)
    		{
    	        std::generate
    	        (
    		    img.buffer.begin(),
    		    img.buffer.end(),
    		    Gen<TYPE_GRAYSCALE>()
    	        );
     
                clock_t t0 = clock();
    			min = std::for_each
    				(
    					img.buffer.begin(),
    					img.buffer.end(),
    					MIN<TYPE_GRAYSCALE>()
    				 ).min;
                tSomme+=clock()-t0;
    		}
    		tempA = double(tSomme)/num;
    		std::cout<<"************MIN**************" <<std::endl;
    		std::cout<<"grayscale""  "<<tempA <<std::endl;
     
    		tSomme =0;
    		RGB<TYPE_RGB> minRGB;
    		for (int i =0;i<num;++i)
    		{
    	    std::generate
    	       (
    		       imgRGB.buffer.begin(),
    		       imgRGB.buffer.end(),
    		       GenRGB<TYPE_RGB>()
    	       );
               clock_t t0 = clock();
    		   minRGB = std::for_each
    				(
    					imgRGB.buffer.begin(),
    					imgRGB.buffer.end(),
    					MINRGB<TYPE_RGB>()
    				 ).min;
               tSomme+=clock()-t0;
    		}
    		tempB = double(tSomme)/num;
    		std::cout<<"rgb "<<minRGB.r<<"  "<<minRGB.g<<"  "<<minRGB.b<<"  "<<tempB <<std::endl;
     
    		std::cout<<"B/A"<<" "<<100*(tempB/tempA)<<"%"<<std::endl;
        }
     
    	return 0;
    }

  9. #29
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par poukill Voir le message
    Re,

    Si, il y a erreur...
    Ton Multiplie prend en parametre template toujours un double, ce qui penalise bcp le GreyScale !
    En mettant bien unsigned short dans les deux, on gagne un facteur 15...
    Et on retrouve bien le greyscale plus rapide et le RGB plus lent avec 200 a 300 % en moyenne...
    Ok. Le problème si tu utilise des unsigned short, tu ne peut multiplier que par des entiers. Puis la tu as le problème inverse pour le rgb. Il est ralentie par la convertion.
    Donc tout dépend de ce que tu veut faire

  10. #30
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    si tu met TYPE_GRAYSCALE pour GRAYSCALE et TYPE_RGB pour RGB, tu es en dessous des 200% voir même plustôt vers 115%

  11. #31
    screetch
    Invité(e)
    Par défaut
    threading + sse2 > micro optimisations.

    regarde du coté de Intel Thread Building Blocks

  12. #32
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Citation Envoyé par Mongaulois Voir le message
    Ok. Le problème si tu utilise des unsigned short, tu ne peut multiplier que par des entiers. Puis la tu as le problème inverse pour le rgb. Il est ralentie par la conversion.
    Donc tout dépend de ce que tu veut faire
    Ca c'est clair... Je ne peux multiplier que par des entiers pour les unsigned short.
    Par contre les RGB étant de base en float dans mon application, le Muliplie<float> ne le ralentira pas. On va dire qu'on est en optimum dans les 2 cas, mais qu'on est dans un cas restreint pour le GreyScale (pas pouvoir mulitplier par un float c'est quand même emmerdant).
    C'est là qu'on voit que la conversion est quand même pénalisante...


    Citation Envoyé par screetch Voir le message
    threading + sse2 > micro optimisations.

    regarde du coté de Intel Thread Building Blocks
    Merci du tuyau. Utilisant une bibliothèque externe commerciale, je ne pense pas pouvoir m'en servir. Le bench que je fais aujourd'hui, c'est pour simuler des performances là où je n'ai pas le code source en optimisant au maximum. J'ai des données GreyScale entier sur 16 bits, et le fournisseur (la lib) ne prend que du RGBA float. Je voudrai donc quantifier cette "perte" pour éventuellement coder tout moi même si je juge que ça ne tiendra pas le temps réel qui m'est imposé...


    J'ai une autre question. Est-ce qu'on pourrait vraiment améliorer ce bench? Je veux dire, une image à base de pointeurs only. Une structure RGB avec un tableau C...

    Merci encore pour votre aide !

  13. #33
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par poukill Voir le message
    J'ai une autre question. Est-ce qu'on pourrait vraiment améliorer ce bench? Je veux dire, une image à base de pointeurs only. Une structure RGB avec un tableau C...
    C'est à dire?

  14. #34
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    J'en sais rien... C'est juste pour pas me retrouver à montrer un bench mal optimisé au concepteur de la bibliothèque, qui va me rire au nez en me disant que tout ça ne veut rien dire...
    Je pensais à un truc du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    struct ImageRGB
    { 
    	ImageRGB(int hh,int ww) :h(hh),w(ww), buffer(new float[hh*ww*3]) {}
    	~ImageRGB() {delete buffer;}
     
        int h;
        int w;
        float *buffer;
    };

  15. #35
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par poukill Voir le message
    J'en sais rien... C'est juste pour pas me retrouver à montrer un bench mal optimisé au concepteur de la bibliothèque, qui va me rire au nez en me disant que tout ça ne veut rien dire...
    Je pensais à un truc du genre:
    Ben on utilise un vector et on parcoure avec les algo donc c'est pareil.
    Aprés tu pourrais aussi
    - aligné la mémoire utilisé. Peut peut être améliorer un peu
    - chercher comment optimiser le cache
    - Peut être optimizer ton traitement dû fait que c'est des entier
    - utiliser l'opérateur [] pour faire du filtrage par exemple
    - accéder sous forme de pointeur en partant de &buffer[0]
    - Visual pro et gcc 4.x implémente OpenMP. Tu pourrais t'en servir pour paralléliser une boucle.
    - dérouler un peu la boucle principale .Genre 4 par 4 Mais je croie que le compilo le fait déjà.
    - déroule les boucles utiliser pour le filtrage.
    - utiliser du SSE
    - TBB pour utiliser leur vector aligné et leur algorithm
    - Peut être GIL de Boost

    Après si tu veut être rigoureux, il faudrait la même image sur les deux versions. Si tu montre que tu as un énorme gain, il ne pourra rien dire.

    Y as aussi une chose pour le filtrage sur le pentium, mais j'ai pas encore tout compris
    http://www.developpez.net/forums/d53...acces-memoire/

  16. #36
    screetch
    Invité(e)
    Par défaut
    je pense que le plus gros gain c'est par SSE2 qui te permettra de faire 4 operations flottantes par "operation". du coup ca peut etre des flottants 32 bits, et donc des RGBA flottants. le plus rapide serait en gros comme tu l'as ecrit, puis :

    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
    struct ImageRGB
    { 
    	ImageRGB(int hh,int ww) :h(hh),w(ww), buffer(new float[hh*ww*3]) {}
    	~ImageRGB() {delete buffer;}
     
        int h;
        int w;
        float *buffer; //must be aligned on 16 bytes
     
      void multiply(float val)
      {
        __m128 by = _mm_set_ps1(val);
        __m128* buffer ? this->buffer;
        for(size_t = 0; t < w*h/4; i+=4, buffer+=4)
        {
            _mm_prefetch(buffer+256);
            buffer[0] = _mm_mul_ps(buffer[0], by);
            buffer[1] = _mm_mul_ps(buffer[1], by);
            buffer[2] = _mm_mul_ps(buffer[2], by);
            buffer[3] = _mm_mul_ps(buffer[3], by);
        }
      }
    };
    Si les images sont grosses ca vaut le coup d'utiliser TBB, sinon c'est inutile, le temps de dispatcher les taches serait superieur au temps d'execution.

  17. #37
    screetch
    Invité(e)
    Par défaut
    c'est aussi un bon moment pour utiliser, sur le code le plus simple possible (donc exit les foncteurs et autres decompositions en pixels minuscules) le simulateur de pipeline deAMD Code Analyst qui te permettra de comparer et de voir les eventues problemes CPU (cache miss, STLF etc)

  18. #38
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Citation Envoyé par Mongaulois Voir le message
    Ben on utilise un vector et on parcoure avec les algo donc c'est pareil.
    Aprés tu pourrais aussi
    - aligné la mémoire utilisé. Peut peut être améliorer un peu
    - chercher comment optimiser le cache
    - Peut être optimizer ton traitement dû fait que c'est des entier
    - utiliser l'opérateur [] pour faire du filtrage par exemple
    - accéder sous forme de pointeur en partant de &buffer[0]
    - Visual pro et gcc 4.x implémente OpenMP. Tu pourrais t'en servir pour paralléliser une boucle.
    - dérouler un peu la boucle principale .Genre 4 par 4 Mais je croie que le compilo le fait déjà.
    - déroule les boucles utiliser pour le filtrage.
    - utiliser du SSE
    - TBB pour utiliser leur vector aligné et leur algorithm
    - Peut être GIL de Boost

    Après si tu veut être rigoureux, il faudrait la même image sur les deux versions. Si tu montre que tu as un énorme gain, il ne pourra rien dire.

    Y as aussi une chose pour le filtrage sur le pentium, mais j'ai pas encore tout compris
    http://www.developpez.net/forums/d53...acces-memoire/
    Merci Mongaulois pour ces précisions.
    De mon côté il faut savoir que mes images sont plutôt petites (300 * 300 à 1000 * 1000). Par contre, j'en ai beaucoup (50 par secondes) !!
    Je vais regarder TBB et openMP, mais je doute que sur des images si petites...

    Citation Envoyé par screetch Voir le message
    je pense que le plus gros gain c'est par SSE2 qui te permettra de faire 4 operations flottantes par "operation". du coup ca peut etre des flottants 32 bits, et donc des RGBA flottants. le plus rapide serait en gros comme tu l'as ecrit, puis :

    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
    struct ImageRGB
    { 
    	ImageRGB(int hh,int ww) :h(hh),w(ww), buffer(new float[hh*ww*3]) {}
    	~ImageRGB() {delete buffer;}
     
        int h;
        int w;
        float *buffer; //must be aligned on 16 bytes
     
      void multiply(float val)
      {
        __m128 by = _mm_set_ps1(val);
        __m128* buffer ? this->buffer;
        for(size_t = 0; t < w*h/4; i+=4, buffer+=4)
        {
            _mm_prefetch(buffer+256);
            buffer[0] = _mm_mul_ps(buffer[0], by);
            buffer[1] = _mm_mul_ps(buffer[1], by);
            buffer[2] = _mm_mul_ps(buffer[2], by);
            buffer[3] = _mm_mul_ps(buffer[3], by);
        }
      }
    };
    Si les images sont grosses ca vaut le coup d'utiliser TBB, sinon c'est inutile, le temps de dispatcher les taches serait superieur au temps d'execution.
    OK. L'utilisation de SSE2 et d'alignement forcé ne risque pas d'être dépendant d'une plateforme cible? Je veux dire par là que je souhaite que mon code soit vraiment portable (au moins Linux et Windows) et pas trop dépendant du type de processeur car ça change beaucoup d'un PC à l'autre.

    Poukill.

  19. #39
    screetch
    Invité(e)
    Par défaut
    a 50 images par secondes ca peut etre plus simple de dispatcher lesi mags sur deux processeurs, pour que chacun travaille a 25 mages par seconde. dans le cas d'un dual core.

    le SSE2 est disponible seulement a partir de pentium 4 je crois, et athlon XP, je dirai qu'a l'heure actuelle 95% des CPU de PC de bureaux l'ont. l'alignement necessaire est le meme, ce n'est pas un gros probleme.

    SSE2 c'est les processeurs de 2001

Discussions similaires

  1. BUFFER D'IMAGE RGB
    Par aziatedu13 dans le forum Traitement d'images
    Réponses: 12
    Dernier message: 27/11/2007, 16h06
  2. Transposée d'une image RGB
    Par silainos dans le forum Images
    Réponses: 4
    Dernier message: 01/10/2007, 03h45
  3. convertir image RGB en HSV
    Par deb_Sous_Python dans le forum Calcul scientifique
    Réponses: 5
    Dernier message: 23/04/2007, 12h25
  4. Réponses: 10
    Dernier message: 18/04/2007, 09h39
  5. Conversion d'une image rgb en hsl
    Par ranell dans le forum Images
    Réponses: 13
    Dernier message: 01/03/2007, 22h03

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