Ist Float langsamer als Double? Läuft ein 64-Bit-Programm schneller als ein 32-Bit-Programm?
Lesezeit: 7 Minuten
Boba Fet
Benutzt float tippen Sie langsamer als mit double Typ?
Ich habe gehört, dass moderne Intel- und AMD-CPUs schneller mit Doubles rechnen können als mit Floats.
Was ist mit mathematischen Standardfunktionen (sqrt, pow, log, sin, cos, etc.)? Ihre Berechnung mit einfacher Genauigkeit sollte erheblich schneller sein, da weniger Gleitkommaoperationen erforderlich sein sollten. Zum Beispiel einfache Genauigkeit sqrt kann einfachere mathematische Formeln als doppelte Genauigkeit verwenden sqrt. Außerdem habe ich gehört, dass mathematische Standardfunktionen im 64-Bit-Modus schneller sind (wenn sie auf einem 64-Bit-Betriebssystem kompiliert und ausgeführt werden). Was ist die endgültige Antwort darauf?
Was ist schneller, mein Ferrari oder Ihr Muldenkipper? Es kommt darauf an – wenn Sie versuchen, die Viertelmeile zu laufen, wahrscheinlich der Ferrari. Wenn Sie versuchen, 5 Tonnen Kies zu bewegen, wahrscheinlich der Muldenkipper. Es hängt davon ab, was Sie tun. Dies ist keine beantwortbare Frage.
– Ken Weiß
21. April 2011 um 1:23 Uhr
@Ken White: Es hängt natürlich davon ab, wer den anderen schleppt!
– Greg Hewgill
21. April 2011 um 1:24 Uhr
Die definitive Antwort ist, dass es auf solche allgemeinen Fragen keine definitive Antwort gibt.
– Tim Sylvester
21. April 2011 um 1:26 Uhr
@Tim Silvester. Ja, sieht so aus, als wäre es nicht so einfach wie ich. Ich müsste mit meinem Code experimentieren, um herauszufinden, wie ich ihn schneller machen kann.
– Boba Fet
21. April 2011 um 1:30 Uhr
@Ken Weiß. Es ist ein mathematisches Zahlenverarbeitungsprojekt. Dauert sehr lange bis es fertig ist. Ich versuche es schneller laufen zu lassen.
– Boba Fet
21. April 2011 um 1:31 Uhr
AnT steht zu Russland
Die klassische x86-Architektur verwendet Gleitkommaeinheiten (FPU), um Gleitkommaberechnungen durchzuführen. Die FPU führt alle Berechnungen in ihren internen Registern durch, die jeweils eine Genauigkeit von 80 Bit haben. Jedes Mal, wenn Sie versuchen, mit zu arbeiten float oder double, wird die Variable zunächst aus dem Speicher in das interne Register der FPU geladen. Das bedeutet, dass es absolut keinen Unterschied in der Geschwindigkeit der eigentlichen Berechnungen gibt, da die Berechnungen in jedem Fall mit voller 80-Bit-Präzision durchgeführt werden. Das einzige, was anders sein könnte, ist die Geschwindigkeit, mit der der Wert aus dem Speicher geladen und das Ergebnis zurück in den Speicher gespeichert wird. Natürlich kann es auf einer 32-Bit-Plattform länger dauern, a double verglichen mit float. Auf einer 64-Bit-Plattform sollte es keinen Unterschied geben.
Moderne x86-Architekturen unterstützen erweiterte Befehlssätze (SSE/SSE2) mit neuen Befehlen, die dieselben Gleitkommaberechnungen durchführen können, ohne die “alten” FPU-Befehle einzubeziehen. Allerdings würde ich auch hier keinen Unterschied in der Rechengeschwindigkeit erwarten float und double. Und da diese modernen Plattformen 64-Bit-Plattformen sind, sollte auch die Lade-/Speichergeschwindigkeit gleich sein.
Auf einer anderen Hardwareplattform könnte die Situation anders sein. Aber normalerweise sollte ein kleinerer Fließkommatyp keine Leistungsvorteile bringen. Der Hauptzweck kleinerer Gleitkommatypen besteht darin, Speicher zu sparen, nicht die Leistung zu verbessern.
Bearbeiten: (Um den Kommentar von @MSalters anzusprechen) Was ich oben gesagt habe, gilt für grundlegende arithmetische Operationen. Wenn es um Bibliotheksfunktionen geht, hängt die Antwort von mehreren Implementierungsdetails ab. Wenn der Gleitkomma-Befehlssatz der Plattform einen Befehl enthält, der die Funktionalität der angegebenen Bibliotheksfunktion implementiert, dann gilt das, was ich oben gesagt habe, normalerweise auch für diese Funktion (das würde normalerweise Funktionen wie sin, cos, sqrt). Für andere Funktionen, deren Funktionalität im FP-Befehlssatz nicht sofort unterstützt wird, kann sich die Situation als erheblich anders erweisen. Das ist durchaus möglich float Versionen solcher Funktionen können effizienter implementiert werden als ihre double Versionen.
Warum sind Floats auf SSE/SSE2 nicht schneller? Ich habe gelesen, dass SSE 4×32-Bit-Floats und nur 2×64-Bit-Doubles gleichzeitig ausführen kann. Ich verwende SSE nicht direkt, aber ich denke, mein Compiler kann einige der einfachen Schleifen vektorisieren, um SSE zu verwenden. Ich verwende Intels Compiler, habe aber das Handbuch noch nicht gründlich gelesen. Ich denke, C # kann keine Schleifen vektorisieren.
– Boba Fet
21. April 2011 um 1:39 Uhr
@Boba Fet: Ich habe nur über nicht vektorisierte Berechnungen nachgedacht. Bei vektorisierten Berechnungen kann es aus den von Ihnen genannten Gründen anders aussehen.
– AnT steht zu Russland
21. April 2011 um 5:45 Uhr
Der Speicherbus ist seit Pentium-Zeiten 64 Bit. Die Beladung von 1 Float oder 1 Double ist gleich. Der Unterschied kommt, wenn Sie mehr als 1 Wert laden, dann können in Float 2 Werte in jeder Transaktion geladen werden.
– Patrick Schlüter
21. April 2011 um 7:54 Uhr
-1. Die Aussage “Die Berechnungen werden mit voller 80-Bit-Präzision durchgeführt” ist irreführend falsch für die Frage: “Standard-Mathematikfunktionen (sqrt, pow, log, sin, cos, etc.”. Ja, die nativen x87-Operationen werden ausgeführt volle Präzision pow ist keine native x87-Operation, sondern eine nicht triviale Funktion. Eine 32-Bit-Implementierung dieser Funktion könnte schneller sein, da sie weniger 80-Bit-Operationen verwendet. (Anmerkung: Das Problem ist viel schlimmer für die neuen mathematischen Funktionen von C99, Quelle: Mr. Plauger)
– MSalter
21. April 2011 um 9:31 Uhr
Peter
Ihre erste Frage wurde hier auf SO bereits beantwortet.
Ihre zweite Frage hängt vollständig von der “Größe” der Daten ab, mit denen Sie arbeiten. Es läuft alles auf die Low-Level-Architektur des Systems hinaus und darauf, wie es mit großen Werten umgeht. 64-Bit-Daten in einem 32-Bit-System würden 2 Zyklen erfordern, um auf 2 Register zuzugreifen. Dieselben Daten auf einem 64-Bit-System sollten nur 1 Zyklus benötigen, um auf 1 Register zuzugreifen.
Alles hängt immer davon ab, was Sie tun. Ich finde, es gibt keine schnellen und festen Regeln, also müssen Sie die aktuelle Aufgabe analysieren und auswählen, was für Ihre Bedürfnisse für diese bestimmte Aufgabe am besten geeignet ist.
Danke für den Link. Es ist überraschend, dass die Verwendung von Float die Dinge langsamer machen kann. Scheint komplizierter zu sein als ich dachte.
– Boba Fet
21. April 2011 um 1:25 Uhr
Ja, es gibt eine Menge Dinge, die wir für selbstverständlich halten. Erst als ich einen Mikroprozessorkurs belegte, verstand ich die ganze Arbeit, die die CPU erfordert, um einfache Dinge wie die Darstellung negativer Zahlen, Dezimalzahlen usw. zu erledigen. Je größer die Daten (mehr Genauigkeit, größere Zahlen), mit denen Sie arbeiten desto mehr Arbeit muss die CPU leisten.
– Peter
21. April 2011 um 1:29 Uhr
Nein, seit dem Pentium sind alle Datenbusse 64bit breit. Laden a double (wenn es ausgerichtet ist) dauert nur 1 Buszyklus.
– Patrick Schlüter
21. April 2011 um 7:57 Uhr
Aus einigen Recherchen und empirischen Messungen, die ich in Java gemacht habe:
Grundlegende arithmetische Operationen mit Doubles und Floats werden auf Intel-Hardware mit Ausnahme der Division im Wesentlichen identisch ausgeführt.
Auf der anderen Seite dauert auf dem Cortex-A8, wie er im iPhone 4 und iPad verwendet wird, selbst “grundlegende” Arithmetik mit Doubles etwa doppelt so lange wie mit Floats (eine Register-FP-Addition auf einem Float dauert etwa 4 ns im Vergleich zu einer Register-FP auf eine doppelte Aufnahme von etwa 9 ns);
Ich habe welche gemacht Timings von Methoden auf java.util.Math (trigonometrische Funktionen usw.), die von Interesse sein könnten – im Prinzip können einige davon bei Gleitkommazahlen schneller sein, da weniger Terme erforderlich wären, um auf die Genauigkeit einer Gleitkommazahl zu berechnen; Auf der anderen Seite sind viele davon „nicht so schlimm, wie Sie denken“;
Es ist auch wahr, dass es besondere Umstände geben kann, in denen zB Probleme mit der Speicherbandbreite die “rohen” Berechnungszeiten überwiegen.
Während auf den meisten Systemen double wird die gleiche Geschwindigkeit wie sein float bei einzelnen werten hast du recht das rechnen funktioniert wie sqrt, sin, usw. in einfacher Genauigkeit sollten viel schneller sein, als sie in doppelter Genauigkeit zu berechnen. In C99 können Sie die verwenden sqrtf, sinfusw. funktioniert, auch wenn Ihre Variablen sind doubleund nutzen Sie den Vorteil.
Ein weiteres Problem, das ich erwähnt habe, ist die Bandbreite des Speichers (und ebenso des Speichergeräts). Wenn Sie mit Millionen oder Milliarden von Werten umgehen müssen, float wird mit ziemlicher Sicherheit doppelt so schnell sein wie double da alles speichergebunden oder io-gebunden sein wird. Dies ist ein guter Grund, es zu verwenden float als Typ in einem Array oder in einigen Fällen auf einem Festplattenspeicher, aber ich würde es nicht als guten Grund für die Verwendung betrachten float für die Variablen, mit denen Sie Ihre Berechnungen durchführen.
Die “native” interne Fließkommadarstellung in der x86-FPU ist 80 Bit breit. Das ist bei beiden anders float (32 Bit) und double (64 Bit). Jedes Mal, wenn sich ein Wert in oder aus der FPU bewegt, wird eine Umwandlung durchgeführt. Es gibt nur einen FPU-Befehl, der a ausführt Sünde Betrieb, und es funktioniert auf der internen 80-Bit-Darstellung.
Ob diese Konvertierung schneller ist für float oder für double hängt von vielen Faktoren ab und muss für eine gegebene Anwendung gemessen werden.
Quantenmechanik
Es kommt auf den Prozessor an. Wenn der Prozessor über native Anweisungen mit doppelter Genauigkeit verfügt, ist es normalerweise schneller, nur mit doppelter Genauigkeit zu rechnen, als einen Gleitkommawert zu erhalten, es in ein Double umzuwandeln, die Arithmetik mit doppelter Genauigkeit durchzuführen und es dann wieder in ein Gleitkomma zu konvertieren .
10560000cookie-checkIst Float langsamer als Double? Läuft ein 64-Bit-Programm schneller als ein 32-Bit-Programm?yes
Was ist schneller, mein Ferrari oder Ihr Muldenkipper? Es kommt darauf an – wenn Sie versuchen, die Viertelmeile zu laufen, wahrscheinlich der Ferrari. Wenn Sie versuchen, 5 Tonnen Kies zu bewegen, wahrscheinlich der Muldenkipper. Es hängt davon ab, was Sie tun. Dies ist keine beantwortbare Frage.
– Ken Weiß
21. April 2011 um 1:23 Uhr
@Ken White: Es hängt natürlich davon ab, wer den anderen schleppt!
– Greg Hewgill
21. April 2011 um 1:24 Uhr
Die definitive Antwort ist, dass es auf solche allgemeinen Fragen keine definitive Antwort gibt.
– Tim Sylvester
21. April 2011 um 1:26 Uhr
@Tim Silvester. Ja, sieht so aus, als wäre es nicht so einfach wie ich. Ich müsste mit meinem Code experimentieren, um herauszufinden, wie ich ihn schneller machen kann.
– Boba Fet
21. April 2011 um 1:30 Uhr
@Ken Weiß. Es ist ein mathematisches Zahlenverarbeitungsprojekt. Dauert sehr lange bis es fertig ist. Ich versuche es schneller laufen zu lassen.
– Boba Fet
21. April 2011 um 1:31 Uhr