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

SL & STL C++ Discussion :

STL, std::vector et SSE2


Sujet :

SL & STL C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 28
    Par défaut STL, std::vector et SSE2
    Bonjour à tous!

    Présentement j'ai affaire à une classe qui implémente un tableau 1d dynamique, appelons-là Table1D. La classe a un comportement semblable à std::vector, sans toutefois être conforme à la STL pour les conteneurs, et en plus, elle est optimisée avec des intructions SSE2. Notamment, le constructeur par copie, ainsi que l'opérateur d'affectation, de Table1D utilise une version personnalisée de memcpy pour utiliser des instructions SSE2, et c'est sensiblement la même situation lorsque Table1D a besoin d'un plus grand espace (allocation d'un nouveau tableau aligné sur 16 octets, copie des éléments avec memcpy).

    Mes problèmes avec cette classe :
    - Très difficile d'utiliser les algorithmes générique de la STL.
    - Un doute sur le comportement du constructeur par copie (et de l'opérateur d'affectation).
    Il prend le pointeur de l'autre instance, ainsi que sa taille, et le copie directement avec un memcpy personnalisée (instructions SSE2).
    En aucun cas le constructeur par copie des objets (si ce sont des objets que Table1D contient) n'est appelé.

    Ce que je pourrais faire pour améliorer la classe Table1D :
    - La rendre conforme à la STL.
    - Une première solution serait de lui ajouter tous les méthodes qu'un conteneur de la STL se doit d'avoir.
    - Une autre solution, serait d'utiliser std::vector, de lui faire un allocateur qui alloue de la mémoire alignée sur 16 octets. Je n'ai aucune idée comment gérer le constructeur par copie et la réallocation tout en utilisant des instructions SSE2.

    Mes questions:
    1. Utiliser la STL avec des instructions SSE2, est-ce possible ?
    2. La pratique d'un constructeur par copie qui prendre le pointeur sur les données et qui fait tout simplement un memcpy (sans invoquer les constructeurs par copie des types d'objets qu'il contient), est-ce une bonne idée ?
    3. Comment avoir le contrôle sur le constructeur par copie et la réallocation de std::vector ?


    Que vous aillez une solution partielle, un petit bout de code ou n'importe quoi d'autre que vous jugez pertinent à dire, ne vous gênez surtout pas svp!


    Merci,
    Mathieu

  2. #2
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    1) laisse faire le compilateur, indique-lui l'architecture et il pourra peut-être utiliser des instructions SSE2. Je sais que gcc ou icc le fait.
    2) Mauvaise idée de manière générale, s'il faut le constructeur pour construire les objets, il faut une recopie, laisse faire une fois de plus le compilateur, il sait mieux que toi.
    3) Pas compris.

  3. #3
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Par défaut
    Il n'est pas vraiment possible d'utiliser directement les instructions SIMD avec la STL.
    De plus inutile de compter sur les compilos pour compiler de manière pertinente avec des instructions MMX/SSE/SSE2/SSE3.

    Le plus simple consiste a priori à déclarer des classes pour chaque élement à mettre dans un contenneur STL. Par exemple double2/float4/complex_float2 pour déclarer des vecteurs du genre vector<float4>.
    Et puis les vecteurs de la STL ne sont pas conçus pour le calcul numérique.

    J'en profite pour faire un peu de pub pour ma bibliothèque, la seule à ma connaissance qui manipule les instructions SIMD aussi efficacement
    (Essayez donc avec Boost, Blitz++ et Co.)
    http://www.ient.rwth-aachen.de/team/...al/genial.html
    Attention, sous licence GPL, et donc pas pour le boulot... j'insiste.

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Il n'est pas vraiment possible d'utiliser directement les instructions SIMD avec la STL.
    Ça ne pose pas vraiment de problème.

    J'en profite pour faire un peu de pub pour ma bibliothèque, la seule à ma connaissance qui manipule les instructions SIMD aussi efficacement
    (Essayez donc avec Boost, Blitz++ et Co.)
    http://www.ient.rwth-aachen.de/team/...al/genial.html
    D'ailleurs, elle fait tellement mieux que toutes les autres bibliothèques reconnues mondialement que personne n'en a jamais entendu parler.

    Attention, sous licence GPL, et donc pas pour le boulot... j'insiste.
    Tu n'as pas du comprendre la licence GPL.

  5. #5
    Membre émérite Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Par défaut
    Citation Envoyé par mat087
    2. La pratique d'un constructeur par copie qui prendre le pointeur sur les données et qui fait tout simplement un memcpy (sans invoquer les constructeurs par copie des types d'objets qu'il contient), est-ce une bonne idée ?
    Réponse oui et non.
    En théorie oui (mais il faut calculer correctement la taille à recopier ... sinon bonjour les problèmes de mémoire ...).
    Maintenant si tu fais un memcpy je suppose que ta zone nouvellement allouée, et qui doit recevoir la copie des données, a été crée avec malloc. Dans ce cas tu ne pourras pas appeller les destructeur sur aucun des éléments de ton nouveau tableau. Ce qui peut être génant ... ;-)

  6. #6
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Par défaut
    Citation Envoyé par loufoque
    D'ailleurs, elle fait tellement mieux que toutes les autres bibliothèques reconnues mondialement que personne n'en a jamais entendu parler.
    J'aime pas ton sarcasme.
    Et oui elle est plus rapide que bon nombre d'autres.
    Montre nous donc ton travail, compare le à d'autres, et confronte le aux commentaires sur une page perso...

    Ça ne pose pas vraiment de problème.
    Il faudrait que tu argumentes et proposes des solutions...
    Je vois pas vraiment de solution efficace et aisée pour utiliser les instructions SIMD dans la STL, c'est bien pour ça que j'ai conçu mes propres containers.


    Citation Envoyé par loufoque
    Tu n'as pas du comprendre la licence GPL.
    Je résumais très/trop fortement. Je sais bien que les entreprises ont le droit de l'utiliser et de vendre éventuellement très cher le produit, mais à condition (généralement inacceptable pour une entreprise) de rendre leurs sources GPL.
    Mais en pratique, il doit y avoir pas mal de gens qui font du copier/coller à partir de code GPL, ni vu ni connu ...

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 28
    Par défaut
    mchk0123:
    Oui la zone mémoire est allouée avec malloc (en fait _mm_malloc). Pour ce qui est de l'appel des destructeurs, il se fait lorsque le type est une classe, si (__is_class(),
    http://msdn2.microsoft.com/en-us/library/ms177194.aspx), il y aura un appel au destructeur.

    Charlemagne:
    Je vais regarder plus en profondeur ta libraire, je lui ai jeté un petit coup d'oeil, ça semble bon. Faut dire que je suis loin d'être un expert avec ce type d'instructions. Alors quand tu dis que "les vecteurs de la STL ne sont pas conçus pour le calcul numérique", j'ai de la difficulté à comprendre pourquoi, si tu le veux bien, pourrais-tu m'expliquer davantage la raison de cette affirmation ?


    Merci!

  8. #8
    Membre émérite Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Par défaut
    Alors oui, si tes conteneurs ne contiendrons jamais de classes (que des pointeurs par exemple), ça peut te simplifier la vie.

    Maintenant s'il existe une bibliothèque qui correspond à ton pb. pourquoi s'en priver ?

  9. #9
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Par défaut
    Citation Envoyé par mat087
    Alors quand tu dis que "les vecteurs de la STL ne sont pas conçus pour le calcul numérique", j'ai de la difficulté à comprendre pourquoi, si tu le veux bien, pourrais-tu m'expliquer davantage la raison de cette affirmation ?
    -Il n'y a quasiment aucun algorithme de calcul (accumulate, inner_product + un ou deux autres) avec lesquels on ne va pas loin. Leur vitesse d'exécution est à 100 lieux de ce qui est faisable (entre autres avec les instructions SIMD).
    -Les valrarray ne sont pas optimisés du tout, et ne servent pratiquement à rien.
    -Pas de matrices
    ...

    Pour faciliter la gestion de la mémoire alignée, voici un allocateur qui marche sous plusieurs systèmes. Si quelqu'un connaît les appels correspondants sous d'autres systèmes, qu'il me le dise. Merci d'avance.

    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
    #if (defined(__ICL) || defined(_MSC_VER) || defined(__ICC))
      #include <fvec.h>
      inline void *aligned_malloc (size_t size, size_t align)  {  return _mm_malloc(size+align,align);  }
      inline void  aligned_free   (void *p)                    {  return _mm_free(p); }
    #elif defined (__CYGWIN__)
      #include <xmmintrin.h>
      inline void *aligned_malloc (size_t size, size_t align)  {  return _mm_malloc(size+align,align);  }
      inline void  aligned_free   (void *p)                    {  return _mm_free(p); }
    #elif defined(__MINGW32__)
      #include <malloc.h>
      inline void *aligned_malloc (size_t size, size_t align)  {  return __mingw_aligned_malloc(size+align,align);  }
      inline void  aligned_free   (void *p)                    {  return __mingw_aligned_free(p);             }
    #elif defined(__FreeBSD__)
      #include <stdlib.h>
      inline void* aligned_malloc (size_t size, size_t align) {  return malloc(size); }
      inline void  aligned_free   (void *p)                   {  return free(p); }
    #else 
      #include <malloc.h>
      inline void* aligned_malloc (size_t size, size_t align) {  return memalign(align,size+align); }
      inline void  aligned_free   (void *p)                   {  return free(p); }
    #endif
     
     
    template<class T, int N=16> class alignment_allocator
    {
      public:
        typedef T value_type;
        typedef size_t size_type;
        typedef ptrdiff_t difference_type;
     
        typedef T* pointer;
        typedef const T* const_pointer;
     
        typedef T& reference;
        typedef const T& const_reference;
     
      public:
        inline alignment_allocator() throw() {}
        template <class T2> inline alignment_allocator(const alignment_allocator<T2,N>&) throw() {}
     
        inline ~alignment_allocator() throw() {}
     
        inline pointer       address(reference       r)       { return &r; }
        inline const_pointer address(const_reference r) const { return &r; }
     
        inline pointer allocate(size_type n) { return (pointer)aligned_malloc(n*sizeof(value_type),N); }
        inline void deallocate(pointer p, size_type) { aligned_free(p); }
     
        inline void construct (pointer p,const value_type& wert)  { new (p) value_type(wert); }
        inline void destroy   (pointer p                       )  { p->~value_type();         }
     
        inline size_type max_size() const throw() { return size_type(-1)/sizeof(value_type); }
     
        template<class T2> struct rebind { typedef alignment_allocator<T2,N> other; };
    };

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 28
    Par défaut
    Merci beaucoup pour toutes ces informations!

Discussions similaires

  1. [STL] qsort() et std::vector<int>
    Par archer dans le forum C++
    Réponses: 3
    Dernier message: 25/11/2008, 20h42
  2. [STL] déclaration et manipulation de std::vector
    Par archer dans le forum SL & STL
    Réponses: 3
    Dernier message: 04/11/2007, 21h56
  3. [STL]std::vector<?> pointeur problème
    Par Vincent157 dans le forum SL & STL
    Réponses: 13
    Dernier message: 04/07/2007, 10h21
  4. Sauvegarde std::vector dans un .ini
    Par mick74 dans le forum MFC
    Réponses: 2
    Dernier message: 12/05/2004, 13h30
  5. STL : std::set problème avec insert ...
    Par Big K. dans le forum MFC
    Réponses: 13
    Dernier message: 08/11/2003, 01h02

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