Alignement en mémoire

Un article de Wikipédia, l'encyclopédie libre.
Aller à : navigation, rechercher

En informatique, l'alignement en mémoire est la façon dont les données et les instructions en langage machine sont organisées en mémoire.

Principe[modifier | modifier le code]

Pour augmenter leurs performances, les processeurs sont souvent reliés à la mémoire vive par un bus plus large que la granularité de leur adressage[Quoi ?] c'est-à-dire la taille des mots machines : ainsi, un processeur capable d'adresser des octets est relié à la mémoire par un bus de 32 bits, soit 4 octets. Si une donnée de 4 octets ne se trouve pas à une adresse divisible par 4, alors il faut deux accès à la mémoire pour l'atteindre, ce qui est plus lent, et cause même une erreur d'alignement dans la plupart des processeurs.

Pour éviter les pertes de performance et les problèmes, les données sont donc alignées avec des multiples de 2, 4, 8… selon les caractéristiques du processeur cible.

L'alignement en mémoire dépend fortement de l'architecture et du compilateur. Il est important de connaitre ces caractéristiques surtout lorsque la place mémoire est importante ainsi que pour la communication entre deux architectures différentes.

Exemple en langage C[modifier | modifier le code]

Soient deux structures de données :

typedef struct _noalign
{
    char c;
    double d;
    int i;
    char c2[3];
}noalign;
 
typedef struct _align
{
    double d;
    int i;
    char c2[3];
    char c;
}align;

Les deux structures contiennent les mêmes membres, on pourrait croire qu'elles ont la même taille. Et faisant l'hypothèse que :

  • le type char fait 1 octet ;
  • le type int fait 4 octets ;
  • le type double fait 8 octets.

alors taille totale pourrait être de 1 + 8 + 4 + 3 × 1 = 16 octets. Or la taille observée est de:

printf("noalign %d\n",sizeof(noalign));
printf("align %d\n",sizeof(align));

respectivement 24 et 16.

En effet la structure align est bien alignée mais pas noalign.

Le compilateur rajoute des bits dits de « padding » pour respecter l'alignement. En fait, noalign ressemble à ceci

typedef struct _noalign_corrige
{
    char c;
    char _pad1[7];
    double d;
    int i;
    char c2[3];
    char _pad2;
}noalign_corrige;

On remarque que _pad1 permet à d de débuter à une adresse multiple de 8. _pad2 complète la structure pour atteindre 24 (multiple de la taille du processeur)

Compilateur[modifier | modifier le code]

Avec GCC l'option -Wpadded permet de savoir si une structure est alignée ou pas.

Voici les messages obtenus lors de la compilation de la structure noalign

Warning padding struct to align 'd' 
Warning padding struct size to alignment boundary