33 votes

Pourquoi le Mac ABI requiert-il un alignement de pile de 16 octets pour x86-32?

Je peux comprendre cette exigence pour le vieux PPC les systèmes RISC et même pour x86-64, mais pour les anciens essayé-et-vrai x86? Dans ce cas, la pile doit être aligné sur 4 octets limites seulement. Oui, certains de la MMX/SSE instructions 16 bits alignements, mais si c'est une exigence de l'appelant, alors il doit assurer les alignements sont corrects. Pourquoi le fardeau de tous les appelant avec une exigence? Cela peut effectivement causer des chutes de performances, car chaque appel-le site doit satisfaire à cette exigence. Ai-je raté quelque chose?

Mise à jour: Après quelques enquête et de consultations auprès de certains collègues, j'ai quelques théories à ce sujet:

  1. La cohérence entre le PPC et x86 et x64 version de l'OS
  2. Il semble que la GCC codegen maintenant constamment un sub esp,xxx et puis "mov"s les données sur la pile plutôt que de simplement faire un "push" de l'enseignement. Cela pourrait en fait être plus rapide sur certains matériels.
  3. Bien que cela complique les sites d'appel un peu, il y a très peu de frais généraux supplémentaires lors de l'utilisation de la valeur par défaut "cdecl" convention dans le cas où l'appelant nettoie la pile.

Le problème que j'ai avec le dernier élément, c'est que pour les conventions d'appel, qui s'appuient sur l'appel de nettoyage de la pile, les exigences ci-dessus vraiment "uglifies" la codegen. Par exemple, ce que certains compilateur a décidé de mettre en œuvre plus rapidement à partir des registres d'appel de style pour son propre usage interne (c'est à dire le code qui n'est pas destiné à être appelé à d'autres langues ou les sources)? Cette pile-alignement chose pourrait écarter certains des gains de performance obtenus par le passage de quelques paramètres dans les registres.

Mise à jour: jusqu'à présent les seules vraies réponses ont été cohérence, mais pour moi c'est un peu trop facile de réponse. J'ai bien plus de 20 ans d'expérience avec l'architecture x86 et de consistance, pas de performance, ou de quelque chose de concret, c'est vraiment la raison, alors j'ai l'honneur de suggérer que c'est un peu naïf pour les développeurs de l'exiger. Ils sont ignorant près de trois décennies d'outils et de soutien. Surtout si ils attendent les fournisseurs d'outils pour adapter rapidement et facilement leurs outils pour leur plate-forme (peut-être pas... c' est Apple...) sans avoir à sauter à travers plusieurs apparemment inutiles cerceaux.

Je vais donner à ce sujet un autre jour, ou alors la fermer...

Liées

30voto

rob mayoff Points 124153

De "Intel®64 et IA-32 Optimisation des Architectures Manuel", la section 4.4.2:

"Pour de meilleures performances, le Streaming SIMD Extensions et Streaming SIMD Extensions 2 besoin de leur mémoire opérandes être aligné sur 16 octets limites. Données non alignées peuvent causer d'importantes pénalités par rapport aux données alignées."

De L'Annexe D:

"Il est important de s'assurer que le cadre de la pile est aligné pour un 16-frontière d'octet à l'entrée de la fonction de garder local __m128 de données, les paramètres, et XMM registre des lieux de déversement alignés tout au long d'une invocation de la fonction."

http://www.intel.com/Assets/PDF/manual/248966.pdf

6voto

David Cournapeau Points 21956

Je ne suis pas sûr car je n'ai pas de preuve de première main, mais je crois que la raison est l'ESS. SSE est beaucoup plus rapide si vos tampons sont déjà alignés sur une limite de 16 octets (movps vs movups), et tout x86 a au moins sse2 pour mac os x. Il peut être pris en charge par l'utilisateur de l'application, mais le coût est assez important. Si le coût global pour le rendre obligatoire dans l'ABI n'est pas trop important, cela peut en valoir la peine. SSE est utilisé de manière assez omniprésente sous mac os X: accélération du framework, etc ...

5voto

Andrew Grant Points 35305

Je crois que c'est pour le maintenir en ligne avec l'ABI x86-64.

3voto

Laurent Etiemble Points 17360

Tout d'abord, notez que les 16 octets de l'alignement est une exception mis en place par Apple pour le Système V IA-32 ABI.

La pile de l'alignement n'est nécessaire que lors de l'appel de fonctions du système, parce que de nombreuses bibliothèques sont à l'aide de l'ESS ou de l'Altivec extensions qui exigent le 16 octets de l'alignement. J'ai trouvé une référence explicite dans le libgmalloc page de MAN.

Vous pouvez parfaitement gérer votre cadre de pile de la manière que vous voulez, mais si vous essayez d'appeler une fonction du système avec le mauvais alignement de la pile, vous allez vous retrouver avec un misaligned_stack_error message.

Edit: Pour l'enregistrement, vous pouvez vous débarrasser des problèmes d'alignement lors de la compilation avec GCC en utilisant le mstack-réaligner option.

2voto

user239558 Points 1548

C'est une question de l'efficacité.

S'assurant de la pile est de 16 octets aligné dans chaque fonction qui utilise le nouveau jeu d'instructions SSE, ajoute beaucoup de frais généraux pour l'utilisation de ces instructions, de réduire efficacement la performance.

D'autre part, garder la pile de 16 octets aligné garantit à tout moment que vous pouvez utiliser les instructions SSE librement sans perte de performance. Il n'y a pas de coût pour ce (coût mesuré dans les instructions au moins). Il s'agit uniquement d'un changement de constante dans le prologue de la fonction.

Gaspiller de l'espace de pile n'est pas cher, c'est probablement la partie la plus chaude de la cache.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X