Le sous-système de mémoire sur un processeur moderne est limité à l'accès à la mémoire avec la granularité et l'alignement de sa taille de mot; c'est le cas pour plusieurs raisons.
La vitesse
Les processeurs modernes ont plusieurs niveaux de mémoire cache dans lesquels les données doivent être extraites; la prise en charge des lectures à un octet rendrait le débit du sous-système de mémoire étroitement lié au débit de l'unité d'exécution (aka lié au processeur); tout cela rappelle à quel point le mode PIO a été dépassé par DMA pour plusieurs des mêmes raisons dans les disques durs.
Le processeur lit toujours à sa taille de mot (4 octets sur un processeur 32 bits), donc lorsque vous effectuez un accès d'adresse non aligné - sur un processeur qui le prend en charge - le processeur va lire plusieurs mots. Le CPU lira chaque mot de mémoire que votre adresse demandée chevauche. Cela provoque une amplification jusqu'à 2 fois le nombre de transactions mémoire nécessaires pour accéder aux données demandées.
Pour cette raison, il peut très facilement être plus lent de lire deux octets que quatre. Par exemple, disons que vous avez une structure en mémoire qui ressemble à ceci:
struct mystruct {
char c; // one byte
int i; // four bytes
short s; // two bytes
}
Sur un processeur 32 bits, il serait très probablement aligné comme indiqué ici:
Le processeur peut lire chacun de ces membres en une seule transaction.
Supposons que vous ayez une version compressée de la structure, peut-être du réseau où elle était emballée pour l'efficacité de la transmission; cela pourrait ressembler à ceci:
La lecture du premier octet sera la même.
Lorsque vous demandez au processeur de vous donner 16 bits à partir de 0x0005, il devra lire un mot à partir de 0x0004 et décaler vers la gauche de 1 octet pour le placer dans un registre 16 bits; un peu de travail supplémentaire, mais la plupart peuvent gérer cela en un seul cycle.
Lorsque vous demandez 32 bits à partir de 0x0001, vous obtenez une amplification 2X. Le processeur lira de 0x0000 dans le registre de résultat et décale 1 octet à gauche, puis relit à partir de 0x0004 dans un registre temporaire, décale 3 octets à droite, puisOR
avec le registre de résultat.
Intervalle
Pour un espace d'adressage donné, si l'architecture peut supposer que les 2 LSB sont toujours à 0 (par exemple, des machines 32 bits) alors elle peut accéder à 4 fois plus de mémoire (les 2 bits sauvegardés peuvent représenter 4 états distincts), soit la même quantité de mémoire avec 2 bits pour quelque chose comme des drapeaux. Enlever les 2 LSB d'une adresse vous donnerait un alignement de 4 octets; également appelé une foulée de 4 octets. Chaque fois qu'une adresse est incrémentée, elle incrémente effectivement le bit 2 et non le bit 0, c'est-à-dire que les 2 derniers bits continueront toujours à l'être 00
.
Cela peut même affecter la conception physique du système. Si le bus d'adresse a besoin de 2 bits de moins, il peut y avoir 2 broches de moins sur le CPU et 2 traces de moins sur le circuit imprimé.
Atomicité
Le CPU peut fonctionner sur un mot de mémoire aligné de manière atomique, ce qui signifie qu'aucune autre instruction ne peut interrompre cette opération. Ceci est essentiel au bon fonctionnement de nombreuses structures de données sans verrouillage et d'autres paradigmes de concurrence .
Conclusion
Le système de mémoire d'un processeur est un peu plus complexe et complexe que celui décrit ici; une discussion sur la manière dont un processeur x86 traite réellement la mémoire peut aider (de nombreux processeurs fonctionnent de la même manière).
Le respect de l'alignement de la mémoire présente de nombreux autres avantages que vous pouvez lire dans cet article IBM .
L'utilisation principale d'un ordinateur est de transformer des données. Les architectures et technologies de mémoire modernes ont été optimisées au fil des décennies pour faciliter l'obtention d'un plus grand nombre de données, d'entrée, de sortie et entre des unités d'exécution plus nombreuses et plus rapides, de manière hautement fiable.
Bonus: Caches
Un autre alignement pour les performances auquel j'ai fait allusion précédemment est l'alignement sur les lignes de cache qui sont (par exemple, sur certains processeurs) 64B.
Pour plus d'informations sur les performances pouvant être obtenues en exploitant les caches, jetez un œil à la Galerie des effets du cache du processeur ; de cette question sur les tailles des lignes de cache
La compréhension des lignes de cache peut être importante pour certains types d'optimisations de programme. Par exemple, l'alignement des données peut déterminer si une opération touche une ou deux lignes de cache. Comme nous l'avons vu dans l'exemple ci-dessus, cela peut facilement signifier que dans le cas mal aligné, l'opération sera deux fois plus lente.