Optimisation Cos et Sin

Programmation d'applications complexes
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Optimisation Cos et Sin

Message par Le Soldat Inconnu »

Salut,

Si vous avez besoin d'utiliser un grand nombre de cos et sin dans des calculs sont pour autant avoir besoin d'une précision maximale, vous pouvez passez par des valeurs précalculées de cos et sin.
Le gain de temps est significatif, entre 6 et 14 fois plus rapide suivant le processeur. Avec une erreur de précision de 0.000001 au maximum.

Voici un exemple de test de rapidité :

Code : Tout sélectionner

#Max = 40000000
Dim Temps(10)

Define Angle.d, Cos.d, Sin.d
Angle = #PI / 5

; Précalcul des sin et cos
#Angle_Resolution = 8000
Global Dim PreCalcul_Cos.d(360 * #Angle_Resolution * 2)
Global Dim PreCalcul_Sin.d(360 * #Angle_Resolution * 2)
For i = -360 * #Angle_Resolution To 360 * #Angle_Resolution
	PreCalcul_Cos(i + (360 * #Angle_Resolution)) = Cos(i * (#PI / (180 * #Angle_Resolution)))
	PreCalcul_Sin(i + (360 * #Angle_Resolution)) = Sin(i * (#PI / (180 * #Angle_Resolution)))
Next

Temps(1) = ElapsedMilliseconds()

For i = 1 To #Max
	
	Cos = Cos(Angle)
	Sin = Sin(Angle)
	
Next

Temps(2) = ElapsedMilliseconds()

For i = 1 To #Max
	
	a = Angle * #Angle_Resolution * 180 / #PI + 360 * #Angle_Resolution
	Cos = PreCalcul_Cos(a)
	Sin = PreCalcul_Sin(a)
	
Next

Temps(3) = ElapsedMilliseconds()

For i = 1 To #Max
	
	a = Angle * (#Angle_Resolution * 180 / #PI) + (360 * #Angle_Resolution)
	Cos = PreCalcul_Cos(a)
	Sin = PreCalcul_Sin(a)
	
Next

Temps(4) = ElapsedMilliseconds()

; Vérification de la précision
ErreurCos.d = 0
ErreurSin.d = 0

For i = 0 To 36000000
	Angle = i / 100000 * (#PI / 180)
	
	a = Angle * (#Angle_Resolution * 180 / #PI) + (360 * #Angle_Resolution)
	
	Erreur.d = PreCalcul_Cos(a) - Cos(Angle)
	If Erreur < 0
		Erreur = -Erreur
	EndIf
	If Erreur > ErreurCos
		ErreurCos = Erreur
	EndIf
	
	Erreur.d = PreCalcul_Sin(a) - Sin(Angle)
	If Erreur < 0
		Erreur = -Erreur
	EndIf
	If Erreur > ErreurSin
		ErreurSin = Erreur
	EndIf
	
Next


; Affichage du résultat
For i = 2 To 4
	If i > 2
		Texte.s + Chr(10)
	EndIf
	Texte.s + Str(Temps(i) - Temps(i - 1))
	If i > 2
		If (Temps(i) - Temps(i - 1)) > (Temps(2) - Temps(1))
			Texte + " ( x " + StrD((Temps(i) - Temps(i - 1)) / (Temps(2) - Temps(1)), 2) + " )"
		Else
			Texte + " ( / " + StrD((Temps(2) - Temps(1)) / (Temps(i) - Temps(i - 1)), 2) + " )"
		EndIf
	EndIf
Next
Texte + Chr(10) + "Erreur de précision Cos : " + StrD(ErreurCos, 20)
Texte + Chr(10) + "Erreur de précision Sin : " + StrD(ErreurSin, 20)
MessageRequester("Temps", Texte)
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: Optimisation Cos et Sin

Message par Fig »

Merci pour l'information.
J'utilisais ça sur cpc pour les rebonds de sprites...
J'ignorais que sur pc la table pré-calculée était toujours plus rapide que l'opération. 8O
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Répondre