Frage

Ich schreibe eine iPhone App, dass Bedürfnisse der Quadratwurzel einer Zahl etwa 2000 mal pro 1 / eines zweiten 30. zu berechnen. sqrt () funktioniert auf einem Computer, aber die Framerate sinkt auf etwa 10 FPS auf einem iPhone oder iPad, und ich habe bereits den Rest des Codes optimiert. Ich habe gehört, dass diese dramatisch beschleunigt werden können, indem die Quadratwurzel zu schätzen, aber ich kann keinen Code finden, um dies zu tun. Ich brauche nur eine oder zwei Dezimalstellen Präzision. Alle Vorschläge, wie dies zu tun, oder andere Wege, um Dinge zu beschleunigen würden geschätzt.

Danke!

War es hilfreich?

Lösung

Wie genau wollen Sie Ihre Schätzung sein? Wenn Sie wissen, wie nah Sie Ihre Schätzung der realen sqrt sein Newton-Verfahren ist dein Freund.

Sie wissen den Bereich der Werte, die sqrt übergeben werden? Wenn so dass Sie einen Blick auf Tabelle bilden können, die beim Start vorberechnet (oder auch von der Festplatte beim Start eingelesen je nachdem, was schneller erwies). Finden in der Nähe in der Tabelle auf Ihre Eingabe und Sie erhalten Ihre Schätzung.

Andere Tipps

Wenn Sie nicht wirklich Notwendigkeit die Quadratwurzel, die quadrierten Werte anstatt die Rohwerte und die Quadratwurzel vergleichen.

Format- ist viel schneller (und genauer) als eine Quadratwurzel, wenn Sie Vergleiche benötigen. Dies ist der Weg, die meisten Spiele, die es tun.

Sie wissen den Bereich der Werte, dass Sie versuchen, die Quadratwurzel zu finden? Angenommen, Sie haben Werte im Bereich von 0 bis 10. Sie können dann ein Array vorauszuberechnen:

sqrt_val[0] = 0;
sqrt_val[1] = 1;
sqrt_val[2] = // the sqrt of 2
...
sqrt_val[10] = // the sqrt of 10

Dann während der Laufzeit nehmen Sie die Zahl, dass Sie die sqrt von konvertieren möchten, dass auf eine ganze Zahl (so zum Beispiel 3.123 wird 3) und verwenden, die als Index (3), um den vorberechneten Wert zu suchen.

Natürlich, wenn Sie eine feinere Auflösung möchten erhöhen Sie können einfach die Anzahl der Elemente im Array.

Zunächst einmal, sind Sie sicher, dass Quadratwurzel tatsächlich die Engpass? Haben Sie profiliert? 2000 Quadratwurzeln alle 1 / 30stel Sekunde ist eigentlich gar nicht so viele, sogar auf einem Handy. Die ARM-Dokumentation zitiert 33 Zyklen für eine einfachgenaue Quadratwurzel und 60 Zyklen für doppelte Genauigkeit; ein 600-MHz-Prozessor kann tun 10 Millionen Quadratwurzeln pro Sekunde (mehr, wenn der Befehl an alle pipelined ist).

Wenn Sie profiliert haben, und Quadratwurzel ist wirklich der Engpass, werden Sie die NEON vrsqrte.f32 Anweisung verwenden. Diese Anweisung ist recht schnell und gibt Ihnen die ungefähren reziproken Quadratwurzeln vier Gleitkommazahlen gleichzeitig. Sie können dann die vmul.f32 Anweisung verwenden ungefähre Quadratwurzeln zu bekommen (wenn auch für viele Anwendungen der reziproke nützlicher als die Quadratwurzel ist selbst).

Vielleicht ist dies für Sie:
Schnelle inverse Quadratwurzel
Wenn diese Methode die Genauigkeit nicht Sie brauchen es gibt auch eine Menge anderer iterative Verfahren, bei denen man mehr oder weniger präzise zwischen Geschwindigkeit und Genauigkeit wählen:
Methoden Quadratwurzeln der Berechnung

Die einfachste Änderung, die Sie auf einem iPhone machen können, ist sqrtf zu verwenden () anstelle von sqrt (). Single precision float Mathematik ist viel schneller als mit doppelter Genauigkeit, vor allem auf Geräte von 3GS Vintage und neueren.

Wenn Sie die Quadratwurzel benötigen ein Pythagoras Dreieck (sqrt (x * x + y * y)), und sowohl die Berechnung der x und y nicht negativ sind, dann eine sehr schnelle Annäherung an das heißt

max(x,y) + min(x,y)*0.333

Dies hat einen maximalen Fehler von 5,7%. Achten Sie auf Verzweigungsfehlvorhersagebus in min () und max () though.

If you have a "normal" positive float or double, not an int, and want to use a table look-up method, you can do two separate table look ups, one for the exponent (re-biased), and one for a few bits of the mantissa (shift and mask bitfield extraction), and then multiply the two table look up results together.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top