2010-10-20 30 views
1

J'ai exécuté quelques tests eprofile d'une zone de code lente. C'est avec Visual Studio 2008 et .NET 2 (entièrement patché). Environ 32% de mon calcul est utilisé par la formule de Haversine. Cela nécessite deux sinus, deux cosinus, une racine carrée et un arc sinus - tout en utilisant la bibliothèque mathématique .NET standard (Math.Sin, Math.Asin, Math.Sqrt). J'ai été capable de mettre en cache facilement les cosinus - résultant en une accélération de 25 à 30% de la fonction Haversine.__CIasin et Arcsine est-il beaucoup plus lent que sinus dans .NET?

Dans le profil, je vois __CIasin_pentium4 et __CIasin qui ne trouvent pas grand-chose sur Google, sauf pour des choses comme les dumps de pile que les gens ont posté. La variante pentium4 capture environ deux fois plus d'échantillons (inclusifs et exclusifs). Je suppose que c'est un arc sinus, mais est-ce vraiment beaucoup plus cher qu'un sinus? Il n'y a aucun signe de sinus dans le profil même si deux fois plus seront calculés.

Ces deux fonctions sont-elles des arcsines, ou s'agit-il d'un sinus? Si non, que représentent-ils?

Oui J'ai vu divers articles et articles sur Internet et ici à propos de fast sines. J'ai vraiment besoin de la précision d'un sinus calculé plutôt que d'une table de recherche ou d'une série Taylor tronquée. J'utilise la Haversine pour calculer et/ou comparer les distances à la surface de la Terre. La précision de 10m (le minimum à mon humble avis pour mon application) équivaut à environ 1/640000 radians. Une pensée pour la vitesse est de multiplier les identités trigonométriques. Bien que cela se traduirait par plus de fonctions trigonométriques, elles deviendraient dépendantes uniquement des points de terminaison individuels et deviendraient donc susceptibles d'être mises en cache. Une autre consiste à déballer l'arcsine et la racine carrée pour mes comparaisons. Je pense que ce dernier a beaucoup de possibilités d'amélioration, mais pour le moment j'essaie de comprendre ce qui prend le temps de traitement et ce que représentent exactement les fonctions __CIasin.

+1

Vous utilisez donc Math.Sin() ou une bibliothèque mathématique externe? – codymanix

+1

Oui, j'utilise les routines standard de la bibliothèque Math - Math.Sin, Math.Asin et Math.Sqrt. Je ne vois pas la racine carrée dans le profil, mais je vois ces deux fonctions de __CIasin - vraisemblablement de l'appel à Math.Asin? – winwaed

Répondre

1

On dirait que le Pentium FPU a des instructions natives pour le sinus et le cosinus (fsin et fcos), mais pas pour l'arcsine. D'où les fonctions __CIasin que je vois sont probablement l'implémentation .NET d'arcsine, que je comprends utilise une série de Taylor. Ceci explique la grande différence de vitesse, de sorte qu'Asin se montre mais le péché ne le fait pas. (ou cos ou sqrt d'ailleurs - ce sont des fonctions natives aussi).

J'ai codé des FPU x86 directement il y a longtemps. Il y a si longtemps, je pense que ça devait être un 8087 - de toute façon le seul trig trigone présent à cette époque était une tangente partielle!

Le prochain travail dans l'optimisation est de déballer l'arcsine et la racine carrée de la Haversine lorsque cela est possible. Les résultats sont utilisés pour les comparaisons simples plus grandes/plus petites que les comparaisons (tri, etc); et comparer avec des valeurs "fixes". Dans les deux cas, il devrait être possible de les déballer. Par exemple. la valeur fixe devient carré (sin (fixe)), et est comparée à ce qui était à l'intérieur du sqrt. Je pense toujours que les identités trig peuvent être une optimisation utile, mais cela compliquerait définitivement le code et introduirait la possibilité d'erreurs.

0

Oui définitivement déballer le sqrt et l'arc-sinus. Les fonctions trigonométriques inverses sont presque toujours plus lentes que leurs homologues directes car les fonctions trigonométriques directes sont généralement implémentées dans la FPU.