Accélération du code : sur AMD64, ne transmettez pas de structures de plus de 16 octets
- Pour améliorer les performances du langage Neat, la méthode de transmission a été modifiée : au lieu de passer un tableau comme un seul paramètre de structure, il est désormais transmis sous forme de trois paramètres pointeurs.
- La raison pour laquelle les tableaux de Neat étaient plus lents que ceux du langage D est qu’un tableau de 24 octets dépasse 16 octets, ce qui entraîne un mode de passage des paramètres différent.
- Selon la spécification de l’ABI SystemV AMD64, toutes les structures de plus de 16 octets sont transmises via un pointeur.
Vérification du problème par benchmark
- Le benchmark a permis de confirmer la différence de performances entre le passage d’une structure et le passage de champs individuels.
- Lorsqu’on transmet une structure, il faut l’allouer sur la pile puis la copier, alors que des champs individuels peuvent être transmis directement via les registres SSE.
- La transmission par champs individuels offre des performances environ 2 fois supérieures à celle du passage d’une structure.
Le choix du concepteur de langage
- Lorsqu’on appelle une API C, il faut respecter l’ABI C, mais les types de haut niveau utilisés en interne n’ont pas nécessairement besoin d’être représentés comme des structures.
- Le concepteur du langage peut décider comment seront transmis les tableaux, tuples et types somme.
- Transmettre séparément les champs des types dépassant 16 octets peut contribuer à améliorer les performances.
L’avis de GN⁺
- Cet article est très utile pour les développeurs qui s’intéressent à l’optimisation logicielle.
- Il montre notamment que, lors du développement d’applications sensibles aux performances, la taille des structures et leur mode de transmission peuvent avoir un impact important.
- Les concepteurs de langages et les développeurs d’API peuvent exploiter ces informations pour identifier des opportunités d’amélioration des performances.
1 commentaires
Avis Hacker News
vec3(3xfloat) passer de 12 à 16 octets. Il s’est avéré que l’utilisation de 16 octets était plus rapide, car mieux alignée sur les lectures de 8 octets. Au final,vec3a été utilisé commevec4. Il est recommandé de toujours effectuer des benchmarks globaux.cdeclpar défaut est utilisée, les structures de plus de 8 octets ne sont pas passées dans les registres.struct Vectorpour le passer par référenceconst struct Vector &. Beaucoup de code C++ sujet à des bugs de pointeur utilisait des pointeurs inutilement, alors qu’un passage par référence aurait été plus simple et plus sûr.