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 :

alignement des données en C


Sujet :

C

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Etudiant
    Inscrit en
    Juillet 2017
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Etudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juillet 2017
    Messages : 5
    Par défaut alignement des données en C
    Bonjour,

    pouvez-vous m'expliquer c'est quoi l'alignement des données en mémoire ?

    Je ne comprends pas pourquoi l'adresse doit être aligné avec le type auquel elle appartient. Par exemple un type int ne pourra avoir comme adresse que des multiples de ce type.

    ou encore souvent pour représenter le RGB en informatique on le code sur 32 bits pour avoir 8 bits de padding donc RGB(X) et donc être aligné sur la frontière 4 bytes. (d'ailleurs qu'est-ce-que cela veut dire être aligné sur une frontière n bytes ?).

    En investiguant le code memchr de la glibc, je me rends compte aussi qu'il aligne l'adresse sur une frontière longword (32 bits).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    /* Handle the first few bytes by reading one byte at a time.
         Do this until CHAR_PTR is aligned on a longword boundary.  */
      for (char_ptr = (const unsigned char *) s;
           n > 0 && (size_t) char_ptr % sizeof (longword) != 0;
           --n, ++char_ptr)
        if (*char_ptr == c)
          return (void *) char_ptr;
    Je suppose qu'ils font cela pour pouvoir travailler sur 4 octets à la fois au lieu de 1 octet.

    J'ai vraiment du mal à visualiser l'alignement des données.

    Merci de votre réponse.

  2. #2
    Expert confirmé
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 226
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 226
    Par défaut
    Ce n'est pas une contrainte du langage C , mais souvent celui du processeur

  3. #3
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    La mémoire est constituée de "mots" auxquels le microprocesseur accède par une "adresse".
    Sur les processeurs actuels, un mot est souvent constitué de 64 bits soit 8 octets successifs.
    Si un int était à l'adresse 5, donc il serait composé des octets d'adresses 5 6 7 et 8. Pour le lire le processeur devrait accéder à 2 mots (1er en : 0 1 2 3 4 5 6 7 et 2nd en : 8 9 10 11 12 13 14 15) c'est possible mais complexe. La plupart des processeurs imposent donc que certaines données doivent être à des adresses garantissant qu'elles ne seront pas à cheval sur des "mots" mémoire.
    D'où le plus souvent :
    • char : aucune contrainte par définition
    • short : doit être aligné 2
    • float : doit être aligné 4
    • long long et double : doivent être alignés 8.
    • int et long : ça dépend du processeur doivent être alignés 4 ou 8.

  4. #4
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 771
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 771
    Par défaut
    On me corrigera, mais l'alignement intervient lorsqu'on déclare un bloc de variables et en particulier avec une structure.

    Le problème c'est la taille finale . Lorsqu'on définit une structure souvent il faut qu'elle ait la bonne taille dans des contexte comme le réseau, les collections par exemple, et on ne veut pas l'embonpoint dû à l'alignement.

  5. #5
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Non, l'alignement n'est pas une contrainte uniquement pour les tableaux ou les structures. C'est plutôt l'inverse : pour respecter des contraintes d'alignement (valables même pour une "variable simple"), le padding apparait dans les structures.

    A noter aussi que certains processeurs interrompent le programme en cas d'accès non alignés. Par un exemple sur un ARM Cortex-M0, un code comme celui-ci peut ou pas planter, selon comment array aura été aligné :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void process(void* array)
    {
        int* p = (int*) array;
        *p = 666; // boum potentiel!
    }
     
    int main(void)
    {   
        char array[71];
        process(array);
    }

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    Etudiant
    Inscrit en
    Juillet 2017
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Etudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juillet 2017
    Messages : 5
    Par défaut
    Ok, donc en résumé l alignement des données est une contrainte du cpu, ça garanti de pouvoir accéder aux données en une fois et donc de s'assurer que les données ne se trouvent pas a cheval sur un autre mot.

    Citation Envoyé par Bktero Voir le message
    Non, l'alignement n'est pas une contrainte uniquement pour les tableaux ou les structures. C'est plutôt l'inverse : pour respecter des contraintes d'alignement (valables même pour une "variable simple"), le padding apparait dans les structures.

    A noter aussi que certains processeurs interrompent le programme en cas d'accès non alignés. Par un exemple sur un ARM Cortex-M0, un code comme celui-ci peut ou pas planter, selon comment array aura été aligné :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void process(void* array)
    {
        int* p = (int*) array;
        *p = 666; // boum potentiel!
    }
     
    int main(void)
    {   
        char array[71];
        process(array);
    }
    Est ce que le compilateur ne peut pas aider a aligner dans ce cas la ?

  7. #7
    Membre averti
    Homme Profil pro
    Etudiant
    Inscrit en
    Janvier 2016
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Etudiant

    Informations forums :
    Inscription : Janvier 2016
    Messages : 54
    Par défaut
    Citation Envoyé par bewwys Voir le message
    Est ce que le compilateur ne peut pas aider a aligner dans ce cas la ?
    Je crois bien qu'il le fait. Mais il peut être parfois nécessaire de faire ça manuellement.

  8. #8
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Dans ce cas-là, non, il ne peut rien faire. Le compilateur n'est pas omniscient non plus et on fait ici quelque chose d'un peu tordu... D'un côté, tu crées une donnée avec ses contraintes d'alignement (ici, aucun, ce sont des char, mais il pourrait y en avoir avec des short, des doubles, etc) ; de l'autre, tu récupères une adresse (par définition, sans contrainte d'alignement) et tu la castes dans un type qui a des contraintes d'alignements, sans vérifier que l'adresse est OK (ici, on pourrait vérifier que l'adresse est multiple de 4). Et le passage de l'un est l'autre est difficile à résoudre à la compilation (en plus, dans le cas où j'ai un tel bug dans un vrai projet, process() était dans une bibliothèque pré-compilée, c'était juste impossible).

    Rappelons quand même que quand tu fais int array[71] ou int v, le compilateur s'assure bien évidemment de l'alignement, tu n'as rien à faire !

  9. #9
    Nouveau membre du Club
    Homme Profil pro
    Etudiant
    Inscrit en
    Juillet 2017
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Etudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juillet 2017
    Messages : 5
    Par défaut
    Hmm, ok donc je dois a chaque fois verifier que une add est aligné au bon type qd je cast du void* en int* par exemple.

    En gros l alignement est quelque chose dont on doit s attarder qd on code au risque d avoir des penalty sur architecture x86 et pire ca peut crasher un programme sur certains types d architecture

  10. #10
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Citation Envoyé par bewwys Voir le message
    Hmm, ok donc je dois a chaque fois verifier que une add est aligné au bon type qd je cast du void* en int* par exemple.
    Quand on caste un pointeur en void*, le cast inverse doit toujours correspondre au type initial, toute autre action doit être vue comme un "Undefined Behaviour".
    Citation Envoyé par bewwys Voir le message
    En gros l alignement est quelque chose dont on doit s attarder qd on code au risque d avoir des penalty sur architecture x86 et pire ca peut crasher un programme sur certains types d architecture
    Il y a pire que le pire : sur certains processeurs ARM, la valeur lue est fausse et il n'y a pas de déclenchement d'exception

    Mais l'erreur d'alignement est toujours due à une énorme bidouille et est donc rarissime en C. J'ai plus souvent vu des problèmes d'erreurs dues à la mauvaise gestion de l'endianness (souvent via un cast entre char* et int*), beaucoup plus subtile à détecter (car se tromper 2 fois, c'est avoir raison )

  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
    Citation Envoyé par bewwys Voir le message
    En gros l alignement est quelque chose dont on doit s attarder qd on code au risque d avoir des penalty sur architecture x86 et pire ca peut crasher un programme sur certains types d architecture
    C'est même pire que ça sur x86: Le x86 est extrêmement permissif pour ce qui est de l'alignement lors des opérations normales. En revanche, il ne garantit l'atomicité d'une simple lecture que si la variable est alignée (ce qui signifie qu'un int non-aligné peut être lu en deux fois, très mauvais si un autre thread le change entretemps) et si on tente une opération comme une incrémentation atomique sur un entier non-aligné, j'ignore ce qui se passe (je dirais que lancer une exception serait le meilleur des cas).

    Là-dessus, on pourrait dire que les architectures qui lancent toujours une exception en cas d'opération non-alignée sont plus sûres... sauf que certains OS traitent l'exception en simulant l'opération comme si de rien n'était, ce qui t'expose aux mêmes risques quant au multithreading...
    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.

Discussions similaires

  1. [2008R2] Alignement des données dans un cube
    Par iCraZy63 dans le forum SSAS
    Réponses: 5
    Dernier message: 10/06/2011, 15h45
  2. [2008R2] Alignement des données dans un cube
    Par iCraZy63 dans le forum SSRS
    Réponses: 1
    Dernier message: 07/06/2011, 17h43
  3. Afficher des données alignées
    Par GreatDeveloperOnizuka dans le forum C#
    Réponses: 0
    Dernier message: 04/02/2010, 16h50
  4. [.NET 2.0] Alignement des données ?
    Par OtI$ dans le forum C#
    Réponses: 2
    Dernier message: 03/10/2007, 09h46
  5. Alignement des données
    Par aurelie83 dans le forum SQL
    Réponses: 6
    Dernier message: 30/09/2007, 17h43

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