Certes, je ne comprends pas. Supposons que vous ayez une mémoire avec un mot mémoire d'une longueur de 1 octet. Pourquoi ne pouvez-vous pas accéder à une variable longue de 4 octets en un seul accès mémoire sur une adresse non alignée (c'est-à-dire non divisible par 4), comme c'est le cas avec des adresses alignées?
197
Réponses:
C'est une limitation de nombreux processeurs sous-jacents. Cela peut généralement être contourné en effectuant 4 récupérations inefficaces d'un octet plutôt qu'une extraction de mot efficace, mais de nombreux spécificateurs de langage ont décidé qu'il serait plus facile de les interdire et de forcer tout à être aligné.
Il y a beaucoup plus d'informations dans ce lien que l'OP a découvertes.
la source
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:
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, puis
OR
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 source
vous pouvez avec certains processeurs ( le nehalem peut le faire ), mais auparavant tous les accès mémoire étaient alignés sur une ligne 64 bits (ou 32 bits), car le bus a une largeur de 64 bits, vous deviez récupérer 64 bits à la fois , et il était beaucoup plus facile de les récupérer en «morceaux» alignés de 64 bits.
Donc, si vous vouliez obtenir un seul octet, vous avez récupéré le bloc 64 bits, puis masqué les bits que vous ne vouliez pas. Facile et rapide si votre octet était à la bonne extrémité, mais s'il était au milieu de ce bloc de 64 bits, vous devrez masquer les bits indésirables, puis déplacer les données au bon endroit. Pire encore, si vous vouliez une variable de 2 octets, mais qui était divisée en 2 morceaux, cela nécessitait le double des accès mémoire requis.
Ainsi, comme tout le monde pense que la mémoire est bon marché, ils ont simplement obligé le compilateur à aligner les données sur la taille des blocs du processeur afin que votre code s'exécute plus rapidement et plus efficacement au prix d'une mémoire gaspillée.
la source
Fondamentalement, la raison est que le bus mémoire a une longueur spécifique qui est beaucoup plus petite que la taille de la mémoire.
Ainsi, le processeur lit le cache L1 sur puce, qui fait souvent 32 Ko de nos jours. Mais le bus mémoire qui connecte le cache L1 au CPU aura la largeur beaucoup plus petite de la taille de la ligne de cache. Ce sera de l'ordre de 128 bits .
Alors:
Les accès mal alignés chevaucheront parfois deux lignes de cache, ce qui nécessitera une lecture de cache entièrement nouvelle afin d'obtenir les données. Il pourrait même manquer tout le chemin vers la DRAM.
De plus, une partie de la CPU devra se tenir debout sur sa tête pour assembler un seul objet parmi ces deux lignes de cache différentes qui contiennent chacune une partie des données. Sur une ligne, ce sera dans les bits d'ordre très élevé, dans l'autre, les bits d'ordre très bas.
Il y aura du matériel dédié entièrement intégré dans le pipeline qui gère le déplacement des objets alignés sur les bits nécessaires du bus de données du processeur, mais un tel matériel peut manquer pour les objets mal alignés, car il est probablement plus logique d'utiliser ces transistors pour accélérer correctement optimisé programmes.
Dans tous les cas, la deuxième lecture de mémoire parfois nécessaire ralentirait le pipeline, quelle que soit la quantité de matériel spécialisé (hypothétiquement et stupidement) dédié à la correction des opérations de mémoire mal alignées.
la source
@joshperry a donné une excellente réponse à cette question. En plus de sa réponse, j'ai quelques chiffres qui montrent graphiquement les effets qui ont été décrits, en particulier l'amplification 2X. Voici un lien vers une feuille de calcul Google montrant à quoi ressemble l'effet des différents alignements de mots. De plus, voici un lien vers un Github avec le code du test. Le code du test est adapté de l'article écrit par Jonathan Rentzsch auquel @joshperry a fait référence. Les tests ont été exécutés sur un Macbook Pro avec un processeur quadricœur Intel Core i7 64 bits à 2,8 GHz et 16 Go de RAM.
la source
x
ety
coordonnées signifient?Si un système avec une mémoire adressable par octets a un bus mémoire de 32 bits de large, cela signifie qu'il existe effectivement des systèmes de mémoire de quatre octets qui sont tous câblés pour lire ou écrire la même adresse. Une lecture alignée sur 32 bits nécessitera des informations stockées dans la même adresse dans les quatre systèmes de mémoire, de sorte que tous les systèmes peuvent fournir des données simultanément. Une lecture 32 bits non alignée nécessiterait que certains systèmes de mémoire retournent des données à partir d'une adresse et certains renvoient des données à partir de l'adresse suivante supérieure. Bien que certains systèmes de mémoire soient optimisés pour pouvoir répondre à ces demandes (en plus de leur adresse, ils ont effectivement un signal «plus un» qui les amène à utiliser une adresse supérieure à celle spécifiée), une telle fonctionnalité ajoute un coût considérable et la complexité d'un système de mémoire;
la source
Si vous disposez d'un bus de données 32 bits, les lignes d'adresse du bus d'adresses connectées à la mémoire commenceront à partir de A 2 , de sorte que seules les adresses alignées 32 bits peuvent être accédées en un seul cycle de bus.
Donc, si un mot couvre une limite d'alignement d'adresse - c'est-à-dire A 0 pour des données 16/32 bits ou A 1 pour les données 32 bits n'est pas égal à zéro, deux cycles de bus sont nécessaires pour obtenir les données.
Certaines architectures / jeux d'instructions ne prennent pas en charge l'accès non aligné et généreront une exception sur de telles tentatives, de sorte que le code d'accès non aligné généré par le compilateur nécessite non seulement des cycles de bus supplémentaires, mais des instructions supplémentaires, ce qui le rend encore moins efficace.
la source
Sur PowerPC, vous pouvez charger un entier à partir d'une adresse impaire sans problème.
Sparc et I86 et (je pense) Itatnium lèvent des exceptions matérielles lorsque vous essayez ceci.
Une charge 32 bits contre quatre charges 8 bits ne fera pas beaucoup de différence sur la plupart des processeurs modernes. Le fait que les données soient déjà en cache ou non aura un effet beaucoup plus important.
la source