FPU et puissance d'un nombre

Signaler
Messages postés
1536
Date d'inscription
samedi 21 décembre 2002
Statut
Membre
Dernière intervention
24 mai 2009
-
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
-
Bonjour,

Voila, j'ai 'codé' 2 fonctions permettant de calculer un nombre n a une puissance exp (la fonction est bourrin, cad pas de decoupages de la fonction selon que le nombre soit pair ou impair..), une en ASM avec les instructions du CPU, et une autre avec les instructions de la FPU (celle dont j'ai vraiment besoin, pour certaines raisons..).
Et j'ai donc décidé de comparer la vitesse des 2fonctions, et la reponse est sans appel : Cpu plus rapide que Fpu (Avec mes fonctions a moi !).
Donc j'aimerais savoir comment 'optimiser' la fonction FPU ci dessous :


__declspec(
naked)
int
__stdcall PuissFPU(
int n,
int exp)


{



__asm {


mov eax, [esp + 8]
//eax == exp


fild [esp + 4]
//empile n, ST(1) == n


fild [esp + 4]
//empile n, ST(0) == n, Contiendra le resultat


sub eax, 1


Deb:


fmul ST, ST(1)


sub eax, 1


test eax, eax


jne Deb


sub esp, 4


fist dword ptr[esp]


mov eax, [esp]


add esp, 4


ret 8


}


}


__declspec(
naked)
int
__stdcall Puiss(
int n,
int exp)


{



__asm {


mov ecx, [esp + 4]


mov edx, [esp + 8]


mov eax, ecx


sub edx, 1


Deb:


imul eax, ecx


sub edx, 1


test edx, edx


jne Deb


ret 8


}


}

Voila, merci d'avance a tous ;)
Amicalement, Alex

+2(p - n)

4 réponses

Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
25
Dans tous les cas il est normal que par FPU soit plus lent qu'avec les 3 registres généraux.
Tu peux gagner un peu en passant les params en registres.
Inutile de déplacer ESP en sortie, c'est trop couteux, surtout si tu indexes sur lui l'instruction suivante.

__declspec(naked) int __fastcall PuissFPU(int n, DWORD exp){ // ECX n, EDX exp
__asm {
mov [esp-4], ecx ; n
dec edx
jle short puissExit
fild dword ptr[esp-4]
fld st(0)
boucle:
fmul st(0), st(1)
dec edx
jne short boucle
fistp dword ptr[esp-4]
fstp st(0)
puissExit:
mov eax, [esp-4]
ret 0
}
}

Je n'ai pas mesuré, je te laisse faire, pas le temps.
Si exp <= 1, je retourne n, c'est pas très orthodoxe, tu adapteras selon besoin.

ciao...
BruNews, MVP VC++
Messages postés
1536
Date d'inscription
samedi 21 décembre 2002
Statut
Membre
Dernière intervention
24 mai 2009
2
En fait, je ne veux pas passer toucher aux registres generaux, c'est ca la raison qui m'a poussé a utiliser le FPU...Parce que dans ma fonction appellante, je dois conserver la valeur presente dans ces registres, donc pas de __fastcall...Donc ca me rassure, merci ;)
Puis ce que je te tiens, je veux decomposer un nombre en tous ses chiffres et partie de ses chiffres de taille egale :

1634 => Soit 1, 6, 3, 4 soit 16, 34
100 => 1, 0, 0

J'utilise pour cela le reste de la division entiere par 10^x mais bien sur, c'est une division et c'est lent, donc je me demandais s'il n'existait pas une maniere de coder ca en deplacant des bits ou un truc plus rapide.

Merci Brunews
A bientot

+2(p - n)
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
25
mais non, une division par une constante, 10 ici, se fait par multiplication, va voir bnultoa dans mes sources.

ciao...
BruNews, MVP VC++
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
25
Je viens de t'envoyer ReciDiv.zip qui te donnera le code asm suivant le diviseur indiqué.

ciao...
BruNews, MVP VC++