Le plus rapide de la mise en œuvre du sinus, du cosinus et de la racine carrée en C++ (n'a pas besoin d'être exacte)

Je suis googler la question pour la dernière heure, mais il y a seulement des points de la Série de Taylor ou un exemple de code qui est soit trop lent ou ne compile pas du tout. Eh bien, la plupart des réponses que j'ai trouvé sur Google "Google, c'est déjà demandé", mais malheureusement ce n'est pas...

Je suis de profilage de mon jeu sur le bas de gamme Pentium 4 et découvert que ~85% du temps d'exécution est perdu sur le calcul de sinus, cosinus et de la racine carrée (à partir de la bibliothèque C++ standard dans Visual Studio), et cela semble être très CPU dépendant (sur mon I7 les mêmes fonctions a obtenu que 5% de temps d'exécution, et le jeu est waaaaaaaaaay plus rapide). Je ne peut pas optimiser ces trois fonctions, ni de calculer le sinus et le cosinus en un seul passage (il y interdépendantes), mais je n'ai pas besoin de trop de résultats précis pour ma simulation, afin que je puisse vivre avec plus rapide rapprochement.

Donc, la question: Quels sont le moyen le plus rapide pour calculer le sinus, le cosinus et la racine carrée de float en C++?

MODIFIER
Table de recherche sont de plus en plus douloureux comme résultant de Cache Miss, c'est bien plus coûteux moderne de la CPU de la Série de Taylor. Les Processeurs sont juste tellement vite ces jours-ci, et le cache n'est pas.

J'ai fait une erreur, je l'ai bien que j'ai besoin de calculer plusieurs factorielles pour les Séries de Taylor, et je vois maintenant, ils peuvent être mis en œuvre sous forme de constantes.

De sorte que la mise à jour question: est-il rapide d'optimisation pour la racine carrée ainsi?

EDIT2

Je suis en utilisant la racine carrée de calculer la distance, pas de normalisation - ne peut pas utiliser rapide inverse de la racine carrée de l'algorithme (comme indiqué dans le commentaire: http://en.wikipedia.org/wiki/Fast_inverse_square_root

EDIT3

Je ne peux pas fonctionner sur des carrés des distances, j'ai besoin de distance exacte pour les calculs

  • Il a été résolu il y a plusieurs années - utilisation précalculées tableau pour obtenir le sinus/cosinus numéros.
  • stackoverflow.com/questions/3688649/...
  • Pour l'inverse de la racine carrée (ce qui est fréquent, puisqu'il est impliqué dans le vecteur de normalisation), il est bien connu de formule (en.wikipedia.org/wiki/Fast_inverse_square_root), mais honnêtement, il est un peu dépassé, et probablement 1.0/sqrt(x) va permettre à certaines d'optimisation du compilateur.
  • jetez un oeil à ce pour le sinus et le cosinus: devmaster.net/forums/topic/4648-fast-and-accurate-sinecosine
  • Ce n'est pas le moyen le plus rapide depuis récemment, la CPU sont waaaay plus rapide maintenant, alors il y a des années et le cache n'est pas beaucoup plus rapide. Je veux dire que le Cache est beaucoup plus douloureux, puis en calculant les sinus à l'aide de Tylor Série
  • Quel est exactement le problème avec les Séries de Taylor? Il ressemble exactement à ce dont vous avez besoin. Il vous permet de calculer sin, cos, tan jusqu'à ce que la précision que vous voulez. Si vous avez de la difficulté à la mettre en œuvre, puis de publier que d'une question distincte. Sinon, les gens ont suggéré une table de recherche qui peut être très bon, mais les recherches peuvent être coûteux aussi. Heureusement, la mise en œuvre est si rapide que vous pouvez faire les tests.
  • Vous avez vraiment besoin d'expliquer davantage sur ce que vous êtes en utilisant les résultats. Il existe une variété de différentes approches à différents compromis, et en fonction de ce que vous faites, vous pouvez également être en mesure d'éviter entièrement les opérations, l'utilisation SIMD, ou amortir leurs coûts à travers un grand nombre de calculs. Il est impossible de vous conseiller sur microoptimisation sans connaître les détails du code spécifique à microoptimised.
  • Pour obtenir un numéro de look-up table) est plus lent que le calcul de la série de Taylor? Et tout le profilage des résultats pour le prouver?
  • Que diriez-dectecting le CPU et l'utilisation d'un natif de l'instruction sur un processeur moderne avec une table de recherche ou d'autres code optimisé sur des machines plus anciennes.
  • Je suis assez sûr que je l'ai vu la comparaison des articles, mais ne peuvent pas les trouver dès maintenant
  • Si vous utilisez le calcul de la distance à des fins de comparaison avec une autre distance, un peu de travail avec le carré de la distance et vous pouvez le faire sans sqrt entièrement.
  • Comme je l'ai poser dessus, pouvez-vous expliquer pourquoi vous êtes le calcul de la distance? par exemple, si vous êtes à faire des calculs afin de la comparer avec quelque chose, ne faites pas de la place de la racine carrée de la valeur à comparer avec la place. De même, si vous expliquez ce que vous faites avec sin/cos il y a peut-être des moyens pour éviter ces opérations.
  • J'ai besoin de distance exacte, que les au carré de la distance de truc ne peut pas être utilisé dans mon cas
  • L'approche habituelle pour la racine carrée est d'obtenir une estimation pour la racine carrée (ou à l'inverse de la racine carrée) à l'aide d'un natif du PROCESSEUR de l'instruction, d'une table de recherche, Carmack la fonction etc, généralement à 1 partie en 64, puis l'utiliser dans de Newton-Raphson jusqu'à ce que vous avez suffisamment de précision (IIRC 4 tours pour plein précision). C'est effectivement ce que la bibliothèque C++ aurez à faire, donc si vous avez besoin d'un résultat exact que les chances sont que l'application que vous utilisez actuellement est déjà optimale et la seule façon d'améliorer serait d'utiliser SIMD (ESS, etc), ou de modification de votre algorithme pour éviter le fonctionnement / de réduire sa fréquence.
  • Quand vous posez ce genre de question, vous devez spécifier des conditions beaucoup plus de précision. Avez-vous des informations sur la distribution des numéros pour lesquels vous aurez à calculer sin/cos/sqrt (dire qu'ils sont tous proches de 0)? Avez-vous des contraintes spécifiques sur la précision (par exemple, le péché(0) absolument être 0)? etc. Toute information supplémentaire donne un moyen d'améliorer la solution.
  • Des tables pour les fonctions trigonométriques sont rarement une bonne idée sur n'importe quel processeur de ces 15 dernières années. Qu'est-ce que votre spécification minimale? Si votre spécification minimale est un Pentium 4 pensez à activer le SSE2 de génération de code et l'utilisation de l'ESS sqrt intrinsèques. Le moteur d'exécution lien de l'ESS des versions optimisées de fonctions trigonométriques ainsi ce qui peut être assez d'un facteur que vous n'avez pas besoin de chercher plus loin.
  • Si la précision est d'aucun intérêt que ce soit, vous pouvez utiliser 0, rapprochant sine, que sa sortie sera dans l'intervalle [-1, 1]. Huhu -- désolé, blague -- juste la vitesse et la précision ont tendance à être liés ensemble, et c'est un peu ambigu quant à quel degré d'approximation est acceptable. Lut ne sont généralement pas si bénéfique ici. J'ai trouvé ces bits tripoter nombre magique des solutions telles que l'id est rapide rsqrt de toujours offrir quelques petits avantages, même si je suis dans le C++03 ère (legacy/plate-forme) et un peu en retard sur la dernière optimiseurs/libs standard. Il y a sin/cos variantes de ces derniers aussi bien.

InformationsquelleAutor PiotrK | 2013-09-06