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 d'alignement sur 128 bits


Sujet :

C++

  1. #1
    Membre éprouvé

    Inscrit en
    Juin 2004
    Messages
    1 397
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 1 397
    Par défaut Problème d'alignement sur 128 bits
    Bonjour à tous !
    Afin d'exploiter les instructions de type SSE2, j'ai besoin d'aligner mes données sur 128 bits.
    Pour cela, j'utilise le mot clé __declspec(align(16)) comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    __declspec(align(16)) short mon_tab[720];
    Ce tableau est déclaré en private dans une classe.

    Lorsque je regarde l'adresse, il m'a aligné ce tableau sur 8 octets !
    J'ai donc l'impression que ça ne sert à rien.
    Y a-t-il quelque chose qui m'échappe ?

    Merci d'avance !

    PS: Je suis sous Visual, mais j'ai le même problème avec le même code sous gcc...

  2. #2
    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
    J'ai jamais vérifié mais j'ai jamais remarqué de problème. Depuis le temps que je l'utilise avec ICL (j'utiilse que rarement VC) j'aurais probablement vu des problèmes.

    Par contre je ne sais pas ce que GCC va faire de ce code, peut-être qu'il l'ignore parce que normalement pour GCC c'est "__attribute__((__aligned__(16)))"

    Petit conseil, j'utilise une définition pour rendre le code plus facilement portable.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #if defined(__ICL) || defined(_MSC_VER)
      #define __aligned __declspec(align(16))
    #elif defined(__GNUC__)
      #define __aligned __attribute__((__aligned__(16)))
    #endif

  3. #3
    Membre éprouvé

    Inscrit en
    Juin 2004
    Messages
    1 397
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 1 397
    Par défaut
    Effectivement, moi aussi j'utilise une définition .
    Donc, je ne comprends pas pourquoi il n'aligne pas sur 16...
    Il peut pourtant !

  4. #4
    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
    Attends, je vais essayer de vérifier...

  5. #5
    Membre éprouvé

    Inscrit en
    Juin 2004
    Messages
    1 397
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 1 397
    Par défaut
    En fait j'ai trouvé pourquoi...
    A l'appel via l'accesseur, l'adresse retournée n'est pas l'adresse de base du tableau (qui est bien alignée sur 16 octets !) mais une adresse à 56 octets de plus.
    Du coup, ce n'est plus aligné sur 16, forcément !
    Merci quand même, ça me rassure quand à l'utilité du mot clé .

  6. #6
    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
    GCC, par exemple, n'honore pas les alignements sur la pile supérieurs à l'alignement de la pile elle-même, qui se trouve être 8 octets sous Linux.
    Même chose pour malloc/new.

    Edit: s/Windows/Linux/

  7. #7
    Membre éprouvé

    Inscrit en
    Juin 2004
    Messages
    1 397
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 1 397
    Par défaut
    OK, en mode debug, il m'aligne comme je lui demande (c'est à dire sur 8), en release, il ne le fait plus...
    Plus précisément, si le tableau est aligné en mémoire, il doit l'être, pour mon cas, sur une adresse de type 0x???????8.
    Or, l'alignement forcé va aligner sur 0 ou 8...
    Comment forcer le 8 ?
    Si l'on peut ?

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Comprend pas tes derniers posts.
    Pourquoi es-tu passé de 16 à 8 ?
    Et que veux-tu voir aligné, finalement ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Membre éprouvé

    Inscrit en
    Juin 2004
    Messages
    1 397
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 1 397
    Par défaut
    J'ai un tableau de int. Ce tableau est alloué dynamiquement (via new[]), et l'adresse de base de ce tableau est alignée sur une adresse qui, aujourd'hui, se termine par 8 (aligné sur 8 octets donc). Afin d'utiliser les instructions rapides de transfert 128 bits (SSE2) j'ai absolument besoin que l'adresse de base soit à une adresse se terminant par 0 (aligné sur 16 octets).
    Comment en être certain ?

    Merci d'avance !

  10. #10
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par progfou
    J'ai un tableau de int. Ce tableau est alloué dynamiquement (via new[]), et l'adresse de base de ce tableau est alignée sur une adresse qui, aujourd'hui, se termine par 8 (aligné sur 8 octets donc). Afin d'utiliser les instructions rapides de transfert 128 bits (SSE2) j'ai absolument besoin que l'adresse de base soit à une adresse se terminant par 0 (aligné sur 16 octets).
    Comment en être certain ?
    Tu alloues 15 octets de plus que necessaire et tu utilises la bonne place dans la zone alouee.

  11. #11
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    une adresse qui, aujourd'hui, se termine par 8 (aligné sur 8 octets donc).
    sur huit octets maximum. Cela pourrait aussi bien être quatre (même si je crois savoir que c'est huit).

    Si aucune fonction Microsoft ne te permet de t'assurer de l'alignement sur 16 octets de l'allocation, tu peux choisir de le faire toi-même en allouant 15 (ou plus) octets supplémentaires et faire toi-même l'ajustement du pointeur retourné...

    Edit: Argh, grillé...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  12. #12
    Membre éprouvé

    Inscrit en
    Juin 2004
    Messages
    1 397
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 1 397
    Par défaut
    Pour le moment Microsoft, mais il faudrait que ce soit portable, donc il me faut un truc simple (je ne dois pas avoir à modifier des centaines de lignes) et efficace.

    J'ai bien pensé à faire un new après un décalage, etc. mais je ne vois pas trop comment m'en sortir.

  13. #13
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Tu peux peut-être modifier ton operator new pour le forcer à aligner sur 16 octets...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Membre éprouvé

    Inscrit en
    Juin 2004
    Messages
    1 397
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 1 397
    Par défaut
    En fait, il me suffit de faire quelque chose comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int *pTmp = new[Size + 15];
    int ipTmp = reinterpret_cast<int>pTmp;
    int *pBufferAligned = pTmp + (ipTmp&0x0F);
    Du coup, pBufferAligned sera forcément aligné, non ?

    Ca signifie qu'il faut bien sûr faire un delete[] sur pTmp...

  15. #15
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Presque. L'arithmetique sur les pointeurs ne fonctionne pas en byte mais d'apres le type pointe.

  16. #16
    Membre éprouvé

    Inscrit en
    Juin 2004
    Messages
    1 397
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 1 397
    Par défaut
    Euh, c'est à dire .

  17. #17
    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
    C'est quoi ces conseils?! Pas la peine d'allouer 15 octets en plus. (et d'avoir pleins de problèmes pour se rappeler de l'adresse initiale pour la désallocation)

    Y'a des fonctions qui font ça pour chaque compilo.
    J'en ai fait un allocateur pour mes besoins persos,pour rendre tout automatique.

    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=16)  {  return _mm_malloc(size,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=16)  {  return _mm_malloc(size,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=16)  {  return __mingw_aligned_malloc(size,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=16) {  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=16) {  return memalign(align,size); }
      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& val)  { new (p) value_type(val); }
        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; };
    };

  18. #18
    Membre éprouvé

    Inscrit en
    Juin 2004
    Messages
    1 397
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 1 397
    Par défaut
    Autant pour la définition des fonctions, je comprends bien, autant pour le template, je ne vois pas comment tu t'en sert.
    Un cas d'école, pour aider à la compréhension ?

  19. #19
    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
    Tout bon allocateur doit prendre un paramètre template. (Un allocateur c'est le dernier paramètre template des containers de la STL...)
    J'ai juste rajouté un paramètre pour définir l'alignement.

  20. #20
    Membre éprouvé

    Inscrit en
    Juin 2004
    Messages
    1 397
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 1 397
    Par défaut
    Je ne maîtrise pas assez le concept pour comprendre ta réponse . J'ai pourtant relu plusieurs fois...

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Afficher un nombre contenu sur 128 bits
    Par yoyo1811 dans le forum x86 32-bits / 64-bits
    Réponses: 4
    Dernier message: 19/04/2009, 00h23
  2. Problème d'alignement sur mon site
    Par bob5243 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 0
    Dernier message: 09/04/2009, 14h29
  3. [AC-2007] Problème Recordset aligné sur BD
    Par mike1310 dans le forum VBA Access
    Réponses: 1
    Dernier message: 09/04/2009, 14h27
  4. [VxiR2] Problème déphasage alignement sur plusieurs tableaux
    Par scalpa63 dans le forum Deski
    Réponses: 5
    Dernier message: 27/03/2009, 11h17
  5. Calcul sur 128 bits
    Par helmis dans le forum Débuter
    Réponses: 7
    Dernier message: 28/08/2008, 11h18

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