Question

Les processeurs 32 bits d'Intel, tels que Pentium, ont un bus de données de 64 bits et extraient donc 8 octets par accès. Sur cette base, je suppose que les adresses physiques émises par ces processeurs sur le bus d'adresses sont toujours des multiples de 8.

Tout d'abord, cette conclusion est-elle correcte?

Deuxièmement, s’il est correct, vous devez 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 sur ces processeurs.

Comment peuvent-ils être justifiés de le faire?

Était-ce utile?

La solution

Le principe de base habituel (extrait des manuels d'optimisation d'Intels et d'AMD) est que chaque type de données doit être aligné sur sa propre taille. Un int32 doit être aligné sur une limite de 32 bits, un int64 sur une limite de 64 bits, etc. Un personnage ira très bien n'importe où.

Une autre règle empirique est bien sûr & "le compilateur a été informé des exigences d’alignement &"; Vous n'avez pas à vous en soucier, car le compilateur sait qu'il faut ajouter le bon remplissage et les décalages pour permettre un accès efficace aux données.

La seule exception concerne les instructions SIMD, dans lesquelles vous devez vous assurer manuellement de l'alignement sur la plupart des compilateurs.

  

Deuxièmement, s’il est correct, alors on   devrait aligner les membres de la structure de 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 en quoi cela fait une différence. La CPU peut simplement émettre une lecture pour le bloc 64 bits contenant ces 4 octets. Cela signifie qu’il reçoit 4 octets supplémentaires avant ou après les données demandées. Mais dans les deux cas, une seule lecture suffit. L’alignement sur 32 bits des données d’une largeur de 32 bits garantit qu’elles ne franchiront pas une limite de 64 bits.

Autres conseils

Le bus physique a une largeur de 64 bits ... multiple de 8 - > oui

TOUTEFOIS, il y a deux autres facteurs à prendre en compte:

  1. Certains jeux d'instructions x86 sont adressés octet. Certains sont alignés sur 32 bits (c'est pourquoi vous avez 4 octets). Mais aucune instruction (de base) n'est alignée sur 64 bits. La CPU peut gérer un accès erroné aux données.
  2. Si vous vous souciez de la performance, vous devriez penser à la ligne de cache, pas à la mémoire principale. Les lignes de cache sont beaucoup plus larges.

Ils sont justifiés car le passage à un alignement sur 8 octets constituerait un changement ABI et que l’amélioration des performances marginales n’en vaut pas la peine.

Comme quelqu'un l'a déjà dit, les cachelines sont importantes. Tous les accès sur le bus de mémoire réel sont en termes de lignes de cache (64 octets sur x86, IIRC). Voir la & Quot; Ce que tout programmeur doit savoir sur la mémoire & Quot; doc qui a déjà été mentionné. Le trafic mémoire réel est donc aligné sur 64 octets.

Pour un accès aléatoire et tant que les données ne sont pas mal alignées (par exemple, si elles franchissent une frontière), je ne pense pas que cela compte beaucoup; l'adresse correcte et le décalage dans les données peuvent être trouvés avec une simple construction AND dans le matériel. Cela devient lent lorsqu'un accès en lecture n'est pas suffisant pour obtenir une valeur. C'est aussi pour cette raison que les compilateurs rassemblent généralement de petites valeurs (octets, etc.) car ils ne doivent pas nécessairement se trouver à un décalage spécifique. les courts-circuits doivent porter sur des adresses paires, 32 bits sur des adresses de 4 octets et 64 bits sur des adresses de 8 octets.

Notez que si vous avez la mise en cache à accès implicite et linéaire, les choses seront différentes.

Le bus 64 bits auquel vous faites référence alimente les caches. En tant que CPU, lisez et écrivez toujours des lignes de cache entières. La taille d'une ligne de cache est toujours un multiple de 8 et son adresse physique est en effet alignée sur des décalages de 8 octets.

Les transferts de cache à registre n’utilisent pas le bus de données externe, la largeur de ce bus n’a donc aucune importance.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top