Je suis conscient de l'impact sur les performances lorsque je mélange des ints signés avec des floats.
Est-ce pire de mélanger des ints non signés avec des flotteurs?
Y at-il un succès lorsque vous mélangez signé / non signé sans float?
Les différentes tailles (u32, u16, u8, i32, i16, i8) ont-elles un effet sur les performances? Sur quelles plateformes?
c++
performance
Luis
la source
la source
Réponses:
La pénalité importante due au mélange des ints (de tout type) et des floats est due au fait que ceux-ci sont dans des ensembles de registres différents. Pour passer d'un jeu de registres à un autre, vous devez écrire la valeur en mémoire et la relire, ce qui entraîne une perte de charge .
Le fait de passer de tailles différentes ou de signer des tailles conserve tout dans le même jeu de registres afin d’éviter les lourdes pénalités. Il peut y avoir de plus petites pénalités dues aux extensions de panneau, etc., mais elles sont beaucoup plus petites qu’un chargement-hit-store.
la source
Je soupçonne que les informations sur la Xbox 360 et la PS3 en particulier seront cachées derrière des murs réservés aux développeurs licenciés, comme la plupart des détails de bas niveau. Cependant, nous pouvons construire un programme x86 équivalent et le désassembler pour avoir une idée générale.
Voyons d’abord ce que l’élargissement des coûts non signés entraîne:
La partie pertinente se désassemble en (utilisant GCC 4.4.5):
Donc, fondamentalement, la même chose - dans un cas, nous déplaçons un octet, dans l'autre, nous déplaçons un mot. Prochain:
Se transforme en:
Ainsi, le coût de l’extension du panneau de signalisation est ce qu’il en coûte
movsbl
plutôt que de le fairemovzbl
- niveau de sous-instruction. C'est fondamentalement impossible à quantifier sur les processeurs modernes en raison de la façon dont les processeurs modernes fonctionnent. Tout le reste, qu'il s'agisse de la vitesse de la mémoire, de la mise en cache ou de ce qui était prévu dans le pipeline, va dominer l'exécution.Après environ 10 minutes d'écriture de ces tests, j'aurais facilement pu trouver un véritable problème de performances. Dès que j'active l'optimisation du compilateur, le code devient méconnaissable pour des tâches aussi simples.
Ce n'est pas un débordement de pile, j'espère donc que personne ici ne dira que la microoptimisation n'a pas d'importance. Les jeux fonctionnent souvent avec des données très volumineuses et très numériques. Par conséquent, une attention particulière aux branches, aux diffusions, à la planification, à l'alignement de la structure, etc. peut donner lieu à des améliorations très critiques. Quiconque a passé beaucoup de temps à optimiser le code PPC a probablement au moins une histoire d'horreur à propos de load-hit-store. Mais dans ce cas, ce n'est pas grave. La taille de stockage de votre type entier n'affecte pas les performances, tant qu'elle est alignée et s'inscrit dans un registre.
la source
Les opérations sur les entiers signés peuvent être plus coûteuses sur presque toutes les architectures. Par exemple, la division par une constante est plus rapide quand elle n'est pas signée, par exemple:
va être optimisé pour:
Mais...
optimisera pour:
ou sur des systèmes où la ramification est bon marché,
Même chose pour le modulo. Ceci est également vrai pour les non-pouvoirs de 2 (mais l'exemple est plus complexe). Si votre architecture ne comporte pas de division matérielle (par exemple, la plupart des processus ARM), les divisions non signées de non-constants sont également plus rapides.
En général, dire au compilateur que les nombres négatifs ne peuvent pas en résulter facilitera l'optimisation des expressions, en particulier celles utilisées pour la terminaison de boucle et d'autres conditions.
En ce qui concerne les tailles de taille différente, oui, il y a un léger impact, mais vous devrez peser cela par rapport à moins de mémoire. De nos jours, vous gagnez probablement plus en accédant à moins de mémoire que vous n'en perdez en augmentant la taille. Vous êtes très loin dans la micro-optimisation à ce stade.
la source
Les opérations avec int signé ou non signé ont le même coût sur les processeurs actuels (x86_64, x86, powerpc, arm). Sur les processeurs 32bits, u32, u16, u8 s32, s16, s8 devraient être les mêmes. Vous pouvez avoir une pénalité avec un mauvais alignement.
Mais convertir int en float ou float to int est une opération coûteuse. Vous pouvez facilement trouver une implémentation optimisée (SSE2, Neon ...).
Le point le plus important est probablement l’accès à la mémoire. Si vos données ne tiennent pas dans le cache L1 / L2, vous perdrez plus de cycle que de conversion.
la source
Jon Purdy dit ci-dessus (je ne peux pas commenter) que unsigned peut être plus lent car il ne peut pas déborder. Je ne suis pas d'accord, l'arithmétique non signée est une arithmétique de moular simple modulo 2 au nombre de bits dans le mot. Les opérations signées peuvent en principe subir des débordements, mais elles sont généralement désactivées.
Parfois, vous pouvez faire des choses intelligentes (mais pas très lisibles), comme empaqueter deux éléments de données ou plus dans un int, et obtenir plusieurs opérations par instruction (arithmétique de poche). Mais tu dois comprendre ce que tu fais. Bien sûr, MMX vous permet de le faire naturellement. Mais parfois, en utilisant la plus grande taille de mot prise en charge par le matériel et en compressant manuellement les données, vous obtenez la mise en œuvre la plus rapide.
Faites attention à l'alignement des données. Sur la plupart des implémentations matérielles, les charges et les magasins non alignés sont plus lents. L'alignement naturel signifie que, pour un mot de 4 octets par exemple, l'adresse est un multiple de quatre et que les adresses de mot sur huit octets doivent être des multiples de huit octets. Cela se répercute sur le SSE (128 bits favorisent un alignement de 16 octets). AVX étendra bientôt ces tailles de registres "vectoriels" à 256 bits, puis à 512 bits. Et les charges / magasins alignés seront plus rapides que ceux non alignés. Pour les geeks matériels, une opération de mémoire non alignée peut couvrir des éléments tels que la ligne de cach et même les limites de page, pour lesquels le matériel doit faire attention.
la source
Il est légèrement préférable d'utiliser des entiers signés pour les index de boucle, car le débordement signé n'est pas défini en C, le compilateur supposera donc que ces boucles ont moins de cas de coin. Ceci est contrôlé par "-fstrict-overflow" de gcc (activé par défaut) et l'effet est probablement difficile à remarquer sans lire la sortie de l'assembly.
Au-delà de cela, x86 fonctionne mieux si vous ne mélangez pas de types, car il peut utiliser des opérandes en mémoire. S'il doit convertir des types (signe ou zéro extension), cela signifie un chargement explicite et l'utilisation d'un registre.
Coller avec int pour les variables locales et la plupart de ceci se produira par défaut.
la source
Comme le souligne celion, la conversion entre ints et floats a essentiellement pour corollaire la copie et la conversion de valeurs entre registres. La seule surcharge des entrées non signées en elles-mêmes provient de leur comportement enveloppant garanti, ce qui nécessite un certain contrôle de débordement dans le code compilé.
La conversion entre entiers signés et non signés n'est en principe pas onéreuse. Différentes tailles de nombre entier peuvent être (infinitésimalement) plus rapides ou plus lentes à accéder en fonction de la plate-forme. De manière générale, la taille de l’entier la plus proche de la taille des mots de la plate-forme sera la plus rapide à accéder, mais la différence de performances globale dépend de nombreux autres facteurs, notamment la taille du cache: si vous utilisez uniquement
uint64_t
lorsque vous avez besoinuint32_t
, Cependant, moins de vos données vont tenir dans la mémoire cache en même temps, et vous risquez d’engendrer une surcharge de charge.C'est quand même un peu excessif d'y penser. Si vous utilisez des types adaptés à vos données, les choses doivent parfaitement fonctionner et la quantité de puissance à gagner en sélectionnant des types basés sur l'architecture est néanmoins négligeable.
la source