double vs. float: Rechngeschwindigkeit
-
(Ich poste mal hier, da es ja im weiteren Sinne um Numerik geht)
In meinem aktuellen Programm scheint es so, als wäre es Geschwindigkeitstechnisch egal, ob ich die numerischen Berechungen einfach oder doppelt genau ausführe. Doppelt kostet zwar doppelten Speicher, aber in etwa die selbe Rechenzeit.
Einzige Ausnahme: Mein (einzige) MKL-LAPACK-Aufruf (gesv) braucht in doppelter Genauigkeit auch deutlich länger.
Ich meine mich zu erinnern, mal gehört zu haben, dass auf modernen Architekturen doppelte und einfache Genauigkeit gleich schnell sein sollen. Stimmt das? Was macht LAPACK dann?
-
Wenn ich mich richtig erinnere rechnet die FPU von x86ern immer mit 80 Bit Genauigkeit. Damit ist es egal, ob du 64 oder 32 Bit Gleitkommazahlen berechnest, nur long doubles mit 128 Bit sollten an sich langsamer sein.
-
Wenn dein Compiler automatisch vektorisiert könnte ich mir schon Unterschiede vorstellen, da man eben doppelt so viele floats in einen SIMD-Vektor packen kann.
P.S. Finde das Forum hier für so eine Frage eher unpassend.
-
Dieser Thread wurde von Moderator/in Christoph aus dem Forum Mathematik und Physik in das Forum Rund um die Programmierung verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
@Mups:
Die Genauigkeit der FP-Berechnungen hängt nicht von der verwendeten Variablen-Breite ab, sondern von der - davon unabhängigen - Genauigkeits-Einstellung. Die man übrigens mit _controlfp() einstellen kann:
http://msdn.microsoft.com/en-us/library/e9b52ceh(VS.80).aspxSoweit ich weiss sind aber auch nur wenige Funktionen betroffen - so Sachen wie sqrt(), log(), sin() etc.
-
hustbaer schrieb:
Soweit ich weiss sind aber auch nur wenige Funktionen betroffen - so Sachen wie sqrt(), log(), sin() etc.
eigentlich nur sqrt und div.
-
.filmor schrieb:
Wenn ich mich richtig erinnere rechnet die FPU von x86ern immer mit 80 Bit Genauigkeit.
Die Zeiten sind faktisch vorbei, denn nur die FPU in den x86 CPUs rechnet mit 80Bit die MMX, XMM Einheiten rechnen mit 128Bit Registern in Single oder Double, da diese schneller sind und nicht als Stack Maschine laufen werden faktisch nur noch die neuen Einheiten genutzt. Einfach mal mit der Zielarchitektur herumprobieren, dann sollte man den Unterschied merken.
-
Rein gefühlsmässig gibt es keinen Unterschied mehr in Sachen Geschwindigkeit; mit SIMD habe ich messbare Unterschiede erkennen können, welche aber unter x86-64 sehr stark abgenommen haben (ich nehme mal an, dass es dabei vor allem auch um Dereferenzierung der Zeiger auf double geht) und praktisch vernachlässigbar sind. Ich habe bei meinem Raytracer nur noch ein typedef decimal, was dann überall für Gleitkommazahlen verwendet wird (z.B. werden dann RGB-Farben als 3x 64-Bit double oder 3x 32-Bit single gespeichert). Ich habe das Programm mit beiden Einstellungen kompiliert und dann synthetisch über 2 bzw. 4 GB Daten zur Verarbeitung erzeugt und diese durchgejagt. Resultat: Die Unterschiede sind recht konstant im Sekundenbereich, wenn der Raytracer fast 10 Minuten arbeitet
-
rapso schrieb:
hustbaer schrieb:
Soweit ich weiss sind aber auch nur wenige Funktionen betroffen - so Sachen wie sqrt(), log(), sin() etc.
eigentlich nur sqrt und div.
div auch?
war mir fast sicher dass div nicht betroffen ist...p.S.: nur um den unnötigen flames vorzugreifen: ich GLAUBE es schon, ich bin nur grad sehr ... verdutzt.
-
hustbaer schrieb:
rapso schrieb:
hustbaer schrieb:
Soweit ich weiss sind aber auch nur wenige Funktionen betroffen - so Sachen wie sqrt(), log(), sin() etc.
eigentlich nur sqrt und div.
div auch?
war mir fast sicher dass div nicht betroffen ist...ja, doch, schon noch div. das sind auch die befehle die mit den controll flags dann andere resultate liefern (und entsprechend schneller/langsammer) sind.
-
Hat die Implementierung von div nichts mit den / und % Operatoren zu tun? Oder wirkt sich die Genauigkeitseinstellung auch auf die aus?
-
Auf "/" wirkt es sich ganz sicher aus, da "/" ja wohl zu "div" compiliert werden wird. Oder sagen wir so: es besteht die Möglichkeit dass es sich auswirkt, da dir wohl kein Compiler garantieren wird eben KEIN "div" für "/" zu verwenden.
"%" funktioniert nicht mit floats/doubles, zumindest nicht in C++.
Und ob es sich auf fmod() auswirkt (fmod = "%" für floats/doubles), weiss ich nicht. Ist aber auch leicht möglich. Bzw. sogar sehr wahrscheinlich.
p.S.: hier wurde "nur" geschrieben, weil wir hier von Assembler-Befehlen reden, und nicht von C/C++/...-Konstrukten.
-
Ups, ich hab da etwas durcheinander gebracht. Da es im Kontext mit sqrt, log, sin etc. stand, dachte ich, es wäre von div aus der Standardbibliothek die Rede. Ich dachte auch gar nicht mehr dran, dass das nur mit int dividieren/Modulo bilden kann. Jetzt ist klar