Alignement de la mémoire sur un processeur Intel 32 bits
les processeurs Intel 32 bits tels que Pentium ont un bus de données 64 bits et donc 8 octets par accès. Basé sur ceci, je suppose que les adresses physiques que ces processeurs émettent sur le bus d'adresse sont toujours des multiples de 8.
tout D'abord, cette conclusion est-elle correcte?
deuxièmement, si elle est correcte, alors on devrait aligner les membres de la structure de données sur une limite de 8 octets. Mais j'ai vu des gens utiliser un alignement de 4 octets à la place ces processeurs.
Comment peut-il être justifié?
5 réponses
la règle habituelle (tirée directement des manuels d'optimisation D'Intels et D'AMD) est que chaque type de données doit être aligné par sa propre taille. Un int32
doit être aligné sur une limite de 32 bits, un int64
sur une limite de 64 bits, et ainsi de suite. Un char conviendra parfaitement n'importe où.
une autre règle empirique est, bien sûr, que"le compilateur a été informé des exigences d'alignement". Vous n'avez pas besoin de vous en inquiéter parce que le compilateur sait ajouter le droit rembourrage et les décalages pour permettre un accès efficace aux données.
la seule exception est lorsque vous travaillez avec des instructions SIMD, où vous devez assurer manuellement l'alignement sur la plupart des compilateurs.
deuxièmement, si elle est correcte, alors un devrait aligner les membres de la structure des données sur une limite de 8 octets. Mais j'ai vu personnes utilisant un alignement de 4 octets au lieu de cela sur ces processeurs.
je ne vois pas comment un différence. Le CPU peut simplement émettre une lecture pour le bloc de 64 bits qui contient ces 4 octets. Cela signifie qu'il obtient 4 octets supplémentaires avant que les données demandées, ou après. Mais dans les deux cas, il suffit d'une seule lecture. L'alignement 32 bits des données 32 bits garantit qu'elles ne franchiront pas une limite de 64 bits.
bus physique est de 64bit de large ...multiple de 8 -- > Oui
cependant, il y a deux autres facteurs à considérer:
- certaines instructions x86 sont adressées byte. Certains sont alignés 32 bits (c'est pourquoi vous avez 4 octets chose). Mais aucune instruction (de base) n'est alignée sur 64bits. L'unité centrale peut gérer un accès mal aligné aux données.
- si vous vous souciez de la performance, vous devriez penser à la ligne de cache, pas à la mémoire principale. Cache les lignes sont beaucoup plus large.
ils sont justifiés de le faire parce que le passage à un alignement de 8 octets constituerait un changement ABI, et l'amélioration marginale du rendement n'en vaut pas la peine.
comme quelqu'un d'autre l'a déjà dit, les lignes de communication ont de l'importance. Tous les accès sur le bus mémoire actuel sont en termes de lignes de cache (64 octets sur x86, IIRC). Voir le doc "What every programmer needs to know about memory" qui a déjà été mentionné. Donc le trafic mémoire réel est de 64 octets alignés.
le bus 64 bits auquel vous faites référence alimente les caches. En tant qu'UNITÉ CENTRALE, lisez et écrivez toujours des lignes de cache entières. De la taille d'une ligne de cache est toujours un multiple de 8, et son adresse physique est en effet aligné à 8 octets décalages.
Les transfertsCache-to-register n'utilisent pas la base de données externe, donc la largeur de ce bus n'est pas pertinente.
pour l'accès aléatoire et aussi longtemps que les données ne sont pas mal alignées (par exemple traverser une frontière), Je ne pense pas qu'il importe beaucoup; l'adresse correcte et l'offset dans les données peuvent être trouvés avec un simple et construire dans le matériel. Il est lent lorsqu'un accès en lecture n'est pas suffisant pour obtenir une valeur. C'est aussi pourquoi les compilateurs mettent habituellement de petites valeurs (octets, etc.).) ensemble parce qu'ils n'ont pas à être à un offset spécifique; les shorts doivent être sur les adresses Pair, 32 bits sur les adresses 4 octets et 64 bits sur des adresses de 8 octets.
notez que si vous avez accès aux données inveled et linear, les choses seront différentes.