Alignement en mémoire

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

En informatique, les contraintes d'alignement en mémoire limitent à certains multiples d'adresse mémoire, où certaines données et instructions machine peuvent être enregistrées. En outre, les optimisations d'alignement mémoire permettent d'influencer la vitesse d'exécution d'un programme uniquement en choisissant bien les adresses.

Principe[modifier | modifier le code]

Pour augmenter leurs performances, les processeurs sont souvent reliés à la mémoire vive par un bus de données plus large que la granularité de leur adressage : par exemple un processeur capable d'adresser individuellement des octets (8 bits), relié à la mémoire par un bus de 4 octets (32 bits). Si une donnée de 4 octets ne se trouve pas à une adresse divisible par 4, alors, selon le modèle de processeur, il y a :

  • violation de contrainte : une erreur d'alignement interrompt l'exécution des instructions ;
  • alignement non optimal : deux fois 4 octets bien alignés sont lus, puis les 4 octets mal alignés sont extraits de ces 8 octets, ce qui prend bien plus de temps que lire 4 octets bien alignés.

La règle généralement applicable pour qu'une donnée soit bien alignée, est qu'elle se trouve à une adresse divisible par sa taille. Ainsi, une donnée occupant un seul byte est toujours bien alignée, une donnée de deux bytes est bien alignée si elle est à une adresse paire, une donnée de 4 bytes est bien alignée si elle est à une adresse divisible par 4, etc. Toutefois, la contrainte d'alignement n'excède pas le matériel sous-jacent.

Les contraintes d'alignement en mémoire dépendent de l'architecture du processeur. L'optimisation de l'alignement est plus subtil, car il peut dépendre de la mémoire cache du processeur, de la pagination de la mémoire virtuelle, et autres caractéristiques de l'accès à la mémoire. Certains compilateurs permettent d'influencer l'alignement des données.

Pratique[modifier | modifier le code]

Les processeurs RISC n'ont généralement qu'une seule taille d'instruction machine, et ces instructions doivent être bien alignées. En revanche, les processeurs CISC ont des instructions de tailles variables. Il peut donc parfois être bénéfique pour les performances d'insérer une opération sans effet (souvent appelée nop) afin que les instructions suivantes soient mieux alignées.

Lorsque des données de tailles différentes sont enregistrées en mémoire les unes à la suite des autres, il peut être utile, voire nécessaire, de laisser des trous entre elles afin qu'elles soient toutes bien alignées. Cela s'observent notamment sur la pile d'exécution et dans les type de donnée composés.

Type de donnée composé en C[modifier | modifier le code]

Soient deux types de donnée composés :

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 donc en déduire qu'elles ont la même taille. Ainsi, en faisant l'hypothèse que :

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

la taille totale serait de 1 + 8 + 4 + 3 × 1 = 16 octets.

Or la taille observée est de:

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

respectivement 24 et 16.

En effet les membres de la structure align sont bien alignés, mais pas ceux de noalign. Le compilateur rajoute des octets 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)

Options de compilation[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

Bibliographie[modifier | modifier le code]

  • (en) C A Reference Manual, 5e édition, Samuel P. Harbison III, Guy L. Steel Jr., Prentice Hall, 2002
    • §6.1.3 Alignement Restrictions
    • §5.6.7 Sizes of Structures
  • (en) GCC 4.9.2 Manual, §3.8 Options to Request or Suppress Warnings