J'ai pris l'exemple de l'exponentielle car justement j'ai beaucoup bossé dessus et sur les différentes manières de l'approximer. Les valeurs en nombre de cycles que je donne sont les valeur réellement mesurées pour l'approximation software dans le cas ou les constantes sont dans le cache L1. Si les constantes ne sont que dans le cache L2, il y a un trou de 17 à 22 cycles en moyenne à rajouter.
Pour la version hardware, ce sont les valeurs théoriques maximum que l'on peut atteindre mais je n'ai pas trop de doute dessus. Le f2xm1 bloque vraiment les ports flottants donc il y a peu de difficultés à prédire la durée.
Pour ce qui est des loads, ils n'ont que peu d'impact lorsqu'ils se font depuis le cache L1. Le port de lecture est saturé sur le début du calcul mais il n'y a pas de cycles perdus, et il est disponible pendant l'étape finale pour charger les données des instructions qui suivent le calcul de l'exponentielle.
Si les constantes ne sont pas dans le cache L1, ça veux généralement dire que tu fais peu appel à ces fonctions et que donc une différence d'une vingtaine de cycles ne changera rien de manière globale.
Pour ce qui est de l'instruction f2xm1, c'est loin d'être la plus lente. Si on oublie fnsave et frstor qui sont un peu hors de propos mais qui culminent à plus de 150 cycles ; on trouve quand même parmi les instructions complexes :
fsin et fcos qui suivant les valeurs d'entrée prennent entre 40 et 100 cycles ;
fsincos qui prend un peu plus d'une centaine de cycles ;
fyl2x et fyl2xp1 qui prennent 80 cycles ;
fptan et fpatan qui prennent en gros 115 cycles.
Dans les fonctions complexes, il n'y a que fsqrt et fscale qui prennent moins (27 et 12 cycles respectivement). La fonction exponentielle est un peu particulière car la réduction est simple et peu se calculer très rapidement. Si on prend le calcul de tan() comme exemple, on peut être en dessous des 115 cycles en soft aussi, mais la réduction est plus complexe et donc l'exemple est moins facile à expliquer.
Ce qu'il faut bien voir c'est que d'un point de vu hardware, la FPU x87 ne fait que survivre comme elle peut et les instructions complexes sont elles bien mortes. Le seul intérêt qu'il reste au x87 c'est la précision sur 80bits, pour tout le reste il faut passer à SSE qui ne dispose pas d'instructions complexes et donc nécessite des implémentations hardware.
Les processeurs récents ont encore de très bon multiplieurs dans la FPU car ce sont les mêmes que pour le SSE mais pour les instructions complexes ça dépend vraiment des générations. Elle sont découpée en un très grand nombre de micro-instructions et leur efficacité varie beaucoup. L'idée c'est de les coder en ajoutant le moins possible de micro-instruction, donc suivant ce qui est disponibles dans le reste du processeur ça deviens très variable.
Par exemple, f2xm1 qui prend 58 cycles sur un core i7 ne prenait que 45 cycles sur un core 2 en 45nm. C'est l'avantage des versions soft, on connais leur comportement de manière beaucoup plus fiable.
Pour ce qui est de faire des calculs sur la FPU et le SSE en même temps je te le déconseille, les deux utilisent les mêmes ports pour leurs micro-instructions et les mêmes unités de calcul. Tu ne peux que perdre en performances de manière globale.
[^] # Re: À propos de SSE et AVX
Posté par beagf . En réponse à la dépêche Intel Sandy Bridge et Linux : état des lieux. Évalué à 7.
J'ai pris l'exemple de l'exponentielle car justement j'ai beaucoup bossé dessus et sur les différentes manières de l'approximer. Les valeurs en nombre de cycles que je donne sont les valeur réellement mesurées pour l'approximation software dans le cas ou les constantes sont dans le cache L1. Si les constantes ne sont que dans le cache L2, il y a un trou de 17 à 22 cycles en moyenne à rajouter.
Pour la version hardware, ce sont les valeurs théoriques maximum que l'on peut atteindre mais je n'ai pas trop de doute dessus. Le f2xm1 bloque vraiment les ports flottants donc il y a peu de difficultés à prédire la durée.
Pour ce qui est des loads, ils n'ont que peu d'impact lorsqu'ils se font depuis le cache L1. Le port de lecture est saturé sur le début du calcul mais il n'y a pas de cycles perdus, et il est disponible pendant l'étape finale pour charger les données des instructions qui suivent le calcul de l'exponentielle.
Si les constantes ne sont pas dans le cache L1, ça veux généralement dire que tu fais peu appel à ces fonctions et que donc une différence d'une vingtaine de cycles ne changera rien de manière globale.
Pour ce qui est de l'instruction f2xm1, c'est loin d'être la plus lente. Si on oublie fnsave et frstor qui sont un peu hors de propos mais qui culminent à plus de 150 cycles ; on trouve quand même parmi les instructions complexes :
Dans les fonctions complexes, il n'y a que fsqrt et fscale qui prennent moins (27 et 12 cycles respectivement). La fonction exponentielle est un peu particulière car la réduction est simple et peu se calculer très rapidement. Si on prend le calcul de tan() comme exemple, on peut être en dessous des 115 cycles en soft aussi, mais la réduction est plus complexe et donc l'exemple est moins facile à expliquer.
Ce qu'il faut bien voir c'est que d'un point de vu hardware, la FPU x87 ne fait que survivre comme elle peut et les instructions complexes sont elles bien mortes. Le seul intérêt qu'il reste au x87 c'est la précision sur 80bits, pour tout le reste il faut passer à SSE qui ne dispose pas d'instructions complexes et donc nécessite des implémentations hardware.
Les processeurs récents ont encore de très bon multiplieurs dans la FPU car ce sont les mêmes que pour le SSE mais pour les instructions complexes ça dépend vraiment des générations. Elle sont découpée en un très grand nombre de micro-instructions et leur efficacité varie beaucoup. L'idée c'est de les coder en ajoutant le moins possible de micro-instruction, donc suivant ce qui est disponibles dans le reste du processeur ça deviens très variable.
Par exemple, f2xm1 qui prend 58 cycles sur un core i7 ne prenait que 45 cycles sur un core 2 en 45nm. C'est l'avantage des versions soft, on connais leur comportement de manière beaucoup plus fiable.
Pour ce qui est de faire des calculs sur la FPU et le SSE en même temps je te le déconseille, les deux utilisent les mêmes ports pour leurs micro-instructions et les mêmes unités de calcul. Tu ne peux que perdre en performances de manière globale.