Page 1 sur 1

Optimisation Cos et Sin

Publié : ven. 09/sept./2011 17:37
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)

Re: Optimisation Cos et Sin

Publié : mer. 28/sept./2011 20:48
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