7 Stimmen

Wirkungsgrad/Geschwindigkeit für trigonometrische Funktionen

In einem Spiel, das ich entwickle, habe ich zwei Punkte, pt1 und pt2, und ich möchte den Winkel zwischen ihnen berechnen. Die Entfernung habe ich bereits in einer früheren Berechnung ermittelt. Der offensichtliche Weg wäre, den horizontalen Abstand über den vertikalen Abstand zu arctanisieren (tan(theta) = opp/adj).

Ich frage mich jedoch, da ich die Entfernung bereits berechnet habe, ob es schneller wäre, Arkussinus/Arkosinus mit der Entfernung und dx oder dy zu verwenden?

Wäre es nicht auch besser, wenn ich in einer Tabelle vorberechne?

7 Stimmen

Vielleicht sollten Sie Ihren Link überprüfen - und aufhören, bei der Arbeit Spiele zu spielen! :-)

7 Stimmen

"Big O"?? Bitte bezeichnen Sie nicht alles, was mit Effizienz zu tun hat, mit dieser Bezeichnung. Die Berechnung wird O(1) sein. Aber das bedeutet gar nichts und schon gar nicht, dass sie schnell ist.

1 Stimmen

Ok, ich habe den Titel geändert. Tut mir leid, ich lerne das Zeug immer noch!

10voto

simon Punkte 6984

Ich vermute, dass hier die Gefahr einer vorzeitigen Optimierung besteht. Seien Sie außerdem vorsichtig mit Ihrer Geometrie. Ihr entgegengesetzter/benachbarter Ansatz ist eine Eigenschaft von rechtwinkligen Dreiecken, ist es das, was Sie tatsächlich haben?

Ich gehe davon aus, dass Ihre Punkte planar sind, so dass sie für den allgemeinen Fall implizit zwei Vektoren aus dem Ursprung darstellen (nennen Sie diese v1 und v2), so dass Ihr Winkel

theta=arccos(dot(v1,v2)/(|v1||v2|)) wobei |.| die Vektorlänge ist.

Ob dies schneller geht, hängt von vielen Faktoren ab (vorausgesetzt, es besteht Bedarf). Kennen Sie die Vektorlängen, oder müssen Sie sie berechnen? Wie schnell können Sie in Ihrer Architektur ein Punktprodukt berechnen? Wie schnell ist acos? An einem gewissen Punkt könnten Tricks wie das Nachschlagen in Tabellen (wahrscheinlich interpoliert) helfen, aber das geht zu Lasten der Genauigkeit.

Es ist alles ein Kompromiss, es gibt wirklich keine allgemeine Antwort auf Ihre Frage.

[Bearbeiten: Kommentar hinzugefügt]

Ich möchte noch einmal betonen, dass das Spiel "x ist am schnellsten" mit modernen Prozessoren und Compilern sowieso ein bisschen ein Kinderspiel ist. Man weiß es erst, wenn man es misst und den generierten Code begutachtet. Wenn Sie den Punkt erreichen, an dem Sie sich wirklich für ein (hoffentlich kleines) Stück Code auf dieser Ebene interessieren, können Sie im Detail herausfinden, was Ihr System tut. Aber das ist sehr mühsam. Vielleicht ist eine Tabelle gut. Vielleicht haben Sie aber auch schnelle Vektorberechnungen und einen kleinen Cache. usw. usw. Es läuft alles auf ein "es kommt darauf an" hinaus. Das tut mir leid. Andererseits, wenn Sie haben nicht den Punkt erreicht, an dem Sie sich wirklich so sehr um dieses Stückchen Code sorgen... Sie sollten wahrscheinlich überhaupt nicht auf dieser Ebene darüber nachdenken. Machen Sie es richtig. Machen Sie es sauber (was sowohl Abstraktion als auch Code bedeutet). Dann kümmern Sie sich um den Overhead.

0 Stimmen

Es ist wirklich nicht klar, warum diese Antwort so hoch bewertet wird. Angesichts seiner Mathematik scheint der Fragesteller nach dem Winkel von pt2 zu suchen, wenn pt1 der lokale Ursprung ist, und atan2 ist die offensichtliche Lösung (vielleicht mit einer Lookup-Tabellen-Optimierung). simons Antwort ist der Winkel sweep von pt1 zu pt2 aus der Sicht des Ursprungs, ein völlig anderes Problem.

0 Stimmen

Sol: Nun, die Frage ist nicht sehr klar formuliert, daher habe ich über den allgemeinen Fall gesprochen (und darauf hingewiesen, die Geometrie zu überprüfen). Ich hatte irgendwie auf eine Klärung gehofft. Selbst wenn atan2 der offensichtliche Ansatz wäre, ging es dem Fragesteller darum, dass dies bei Kenntnis der Entfernung nicht der schnellste Weg ist (was stimmt), und er wollte den schnellsten Ansatz. Dieser letzte Teil ist wirklich nicht offensichtlich.

10voto

Ethan Punkte 508

Abgesehen von all den klugen Kommentaren zur verfrühten Optimierung, sollten wir einfach davon ausgehen, dass dies der Hotspot ist und eine verdammte Benchmark :

bar char

Die Zeiten sind in Nanosekunden angegeben und so skaliert, dass sich die "acos" zwischen den Systemen normalisieren.
acos" nimmt einfach den Einheitsradius an, d. h. acos(adj) acos+div" hingegen bedeutet acos(adj/hyp) .

System 1 ist ein 2.4GHz i5 mit Mac OS X 10.6.4 (gcc 4.2.1)
System 2 ist ein 2.83GHz Core2 Quad mit Red Hat 7 Linux 2.6.28 (gcc 4.1.2)
System 3 ist ein 1.66GHz Atom N280 mit Ubuntu 10.04 2.6.32 (gcc 4.4.3)
System 4 ist ein 2.40GHz Pentium 4 mit Ubuntu 10.04 2.6.32 (gcc 4.4.3)

Zusammenfassung: Die relative Leistung ist sehr unterschiedlich. Manchmal ist atan2 schneller, manchmal ist es langsamer. Seltsamerweise ist auf manchen Systemen acos mit einer Division schneller als ohne. Testen Sie auf Ihrem eigenen System :-/

5voto

Chris Ballance Punkte 32892

Wenn Sie das tun wollen viele Zeiten, in einer Tabelle vorberechnen. Die Leistung wird auf diese Weise viel besser sein.

0 Stimmen

Da die Daten vor dem Nachschlagen in der Tabelle normalisiert werden müssen und Sie wahrscheinlich auch zwischen tabellierten Werten interpolieren müssen, ist die Vorberechnung kein eindeutiger Gewinn, es sei denn, es gibt einen Kompromiss zwischen Geschwindigkeit und Genauigkeit, der akzeptabel ist.

0 Stimmen

Da es sich um ein Spiel handelt, ist die Genauigkeit vielleicht nicht so wichtig wie die Geschwindigkeit.

2 Stimmen

Das Vorberechnen ist auf einer modernen CPU nicht unbedingt schneller. Es hängt viel von Dingen wie Cache-Misses ab.

5voto

Mike Dunlavey Punkte 39339

Hier gibt es viele gute Antworten.

Übrigens, wenn Sie die Math.atan2 erhalten Sie 2 volle Blickwinkel.

Ich würde es einfach tun und dann mit Vollgas fahren. Wenn du die Geschwindigkeit nicht magst, und wenn die Stichproben zeigen, dass Sie sich tatsächlich die meiste Zeit in diesem Code befinden und nicht an einem anderen Ort , Versuchen Sie, sie durch eine Tabellenabfrage zu ersetzen. Wenn Sie keine Genauigkeit von weniger als 1 Grad benötigen, können Sie eine ziemlich kleine Tabelle und Interpolation verwenden.

Möglicherweise möchten Sie die Funktion auch in einem Memo speichern. Warum etwas neu berechnen, was Sie bereits vor kurzem getan haben?

Hinzugefügt: Wenn Sie eine Tabelle verwenden, muss diese nur Winkel von 0-45 Grad abdecken (und sie kann hart kodiert werden). Alles andere kann man durch Symmetrie erreichen.

0 Stimmen

Mein einziger Kritikpunkt an dieser Antwort ist: "Hier gibt es eine Menge guter Antworten." Unsinn, das ist die einzige anständige Antwort. Ich würde ihr eine +8 geben, wenn ich könnte.

0 Stimmen

@Sol: Ich fühle mich geschmeichelt, obwohl ich die meisten anderen Antworten für gut halte, und das sage ich nicht immer.

1voto

Harper Shelby Punkte 16295

Vom reinen Geschwindigkeitsstandpunkt aus gesehen wäre eine vorberechnete Tabelle und eine Suche nach der nächsten Übereinstimmung am besten. Es bringt natürlich einen gewissen Overhead mit sich, je nachdem, wie feinkörnig der Winkel sein muss, aber das ist es mehr als wert, wenn man diese Berechnung häufig durchführt (oder in einer engen Schleife), da dies teure Berechnungen sein werden.

0 Stimmen

Wenn Sie es brauchen vraiment feinkörnig ist, landet man wahrscheinlich in einem Bereich, in dem Interpolation, sogar lineare Interpolation für "glatte" Funktionen wie Sinus/Cosinus, sehr gut funktioniert. Eine große Tabelle ist überhaupt nicht nötig.

0 Stimmen

Nachschlagetabellen sind nicht unbedingt schneller.

0 Stimmen

@gs: Nein, aber oft sind sie es (sonst wären sie ja nicht so beliebt). Zugegeben, für manche Berechnungen und manche Hardware sind sie nicht schneller. Bei typischen Desktop-Computern und trigonometrischen Funktionen gewinnen sie AFAIK. Ich weiß nicht, ob GPU-Code-Tricks verwendet werden können, um die Arbeit schneller zu erledigen - wenn ja, großartig (aber das ist ein ganz anderer Trick!).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X