J'ai couru dans un problème curieux. Un algorithme que je travaille est consiste en beaucoup de calculs comme celui-ci où la longueur de la sommation est comprise entre 4 et 7. p> Les calculs d'origine sont tous terminés en utilisant 64 -Bit précision. Pour expérimentation, j'ai essayé d'utiliser une précision 32 bits pour les valeurs d'entrée X, Y, Z (de sorte que les calculs sont effectués à l'aide de 32 bits) et de stocker le résultat final sous forme de valeur 64 bits (coulé simple). P> Je m'attendais aux performances 32 bits pour être meilleures (taille de cache, Taille SIMD , etc.) , mais à ma grande surprise, il n'y avait pas de différence de performance, peut-être même diminuer. P> L'architecture en question est Intel 64, Linux et GCC . Les deux codes semblent utiliser SSE et les tableaux dans les deux cas sont alignés sur 16 limites d'octets. < / P> Pourquoi ce serait-il? Je suppose que jusqu'à présent est que la précision 32 bits ne peut utiliser SSE uniquement sur les quatre premiers éléments, le reste étant composé en série par une surcharge moulé. P> P>
3 Réponses :
sur X87 au moins, tout est réellement fait en précision de 80 bits en interne. La précision détermine vraiment le nombre de ces bits stockés en mémoire. Cela fait partie de la raison pour laquelle différents paramètres d'optimisation peuvent modifier des résultats légèrement: ils changent la quantité d'arrondi de 80 bits à 32-2 ou 64 bits. p>
En pratique, en utilisant un point flottant 80 bits ( En ce qui concerne les optimisations de SIMD, il convient de noter que la plupart des compilateurs sont horribles au code vectorisant automatiquement. Si vous ne voulez pas écrire directement dans la langue d'assemblage, le meilleur moyen de tirer parti de ces instructions est d'utiliser des éléments tels que des opérations de réseau, qui sont disponibles, par exemple, en D et mis en œuvre en termes d'instructions SSE. De même, en C ou C ++, vous voudriez probablement utiliser une bibliothèque de haut niveau de fonctions optimisées par SSE, bien que je ne connaisse pas d'une bonne du sommet de ma tête parce que je programme surtout dans d. p> double Long code> in c et c ++,
réel code> in d) est généralement lent car il n'y a pas de moyen efficace de charger et de stocker 80 bits de la mémoire. Les 32- et 64 bits sont généralement également rapides à condition que la bande passante de la mémoire ne soit pas le goulot d'étranglement, c'est-à-dire si tout est dans la cache de toute façon. 64 bits peut être plus lent si l'un des éléments suivants arrive: p>
"x87" - légèrement mieux que ces vieux processeurs X86. :-)
C'est probablement parce que votre processeur fait toujours le comptage 64 bits, puis couper le nombre. Il y avait du drapeau de la CPU que vous pourriez changer, mais je ne me souviens pas ... p>
Vérifiez d'abord l'ASM qui est produit. Ce n'est peut-être pas ce que vous attendez.
Essayez également d'écrire comme une boucle: p> Certains compilateur peuvent remarquer la boucle et non la forme déroulée. P> Enfin, votre code utilisé () code> plutôt que
[] code>. Si votre code apporte beaucoup d'appels de fonctions (12 à 21), cela allouera le coût de la FP et même enlever le calcul de la FP tous ensemble ne fera pas beaucoup de différence. Indication OTOH pourrait. p> p>
merci, effectivement q () code> sont des macros convertissant directement en accès à pointeur brut
@AAA: Eh bien, s'il y a des mathématiques du tout, cela pourrait encore être un pourcentage important. De plus, je ne sais pas à quel point le compilateur traite avec le mélange de FP et d'autres choses. Cela pourrait suffire à la bloquer d'utiliser des opérations vectorielles.
Vous avez ajouté une bounty - qu'est-ce que vous n'avez pas aimé la réponse de Dsimcha? Il peut également être utile d'essayer le plus récent GCC que vous pouvez ou compilateur d'Intel logiciel.intel.com/en-us/articles/... pour voir s'ils font une meilleure compilation / vectorielle.
@HUP J'aime sa réponse, je voudrais néanmoins d'autres opinions aussi, alors je mets une prime