An jedem Ort, den ich gesehen habe, heißt es, dass double
das float
in fast jeder Hinsicht überlegen ist . float
wurde double
in Java überholt , warum wird es also immer noch verwendet?
Ich programmiere viel mit Libgdx und sie zwingen Sie zur Verwendung float
(DeltaTime usw.), aber es scheint mir, dass double
die Arbeit mit Libgdx in Bezug auf Speicher und Arbeitsspeicher einfacher ist.
Ich lese auch Wann verwenden Sie float und wann double , aber wenn float
es wirklich nur für Zahlen mit vielen Nachkommastellen gut ist, warum können wir dann nicht einfach eine der vielen Variationen von verwenden double
?
Gibt es einen Grund, warum die Leute darauf bestehen, Schwimmer zu verwenden, obwohl dies keine wirklichen Vorteile mehr hat? Ist es einfach zu viel Arbeit, um alles zu ändern?
quelle
byte
undshort
undint
wann ist eslong
?Antworten:
LibGDX ist ein Framework, das hauptsächlich für die Spieleentwicklung verwendet wird.
In der Spieleentwicklung muss man normalerweise eine Menge Zahlen in Echtzeit schreiben und jede Leistung, die man bekommen kann, ist von Bedeutung. Das ist der Grund, warum Spieleentwickler normalerweise float verwenden, wenn die float-Präzision ausreicht.
Die Größe der FPU-Register in der CPU ist nicht das einzige, was Sie in diesem Fall berücksichtigen müssen. Tatsächlich wird der Großteil der Probleme bei der Entwicklung von Spielen von der GPU verursacht, und die GPUs sind in der Regel für Floats optimiert, nicht für Double .
Und dann gibt es noch:
Dies sind alles wertvolle Ressourcen, von denen Sie doppelt so viel erhalten, wenn Sie 32-Bit-Float anstelle von 64-Bit-Double verwenden.
quelle
Floats belegen halb so viel Speicher wie Doubles.
Sie haben möglicherweise eine geringere Präzision als Doppelte, aber viele Anwendungen erfordern keine Präzision. Sie haben eine größere Reichweite als alle ähnlich großen Festkommaformate. Daher füllen sie eine Nische, die große Zahlenbereiche erfordert, aber keine hohe Präzision erfordert und bei der die Speichernutzung wichtig ist. Ich habe sie in der Vergangenheit zum Beispiel für große neuronale Netzwerksysteme verwendet.
Außerhalb von Java werden sie auch häufig in 3D-Grafiken verwendet, da sie von vielen GPUs als primäres Format verwendet werden. Außerhalb von sehr teuren NVIDIA Tesla / AMD FirePro-Geräten ist die Gleitkommazahl mit doppelter Genauigkeit auf GPUs sehr langsam.
quelle
Rückwärtskompatibilität
Dies ist der Hauptgrund für das Beibehalten des Verhaltens in einer bereits vorhandenen Sprache / Bibliothek / ISA / etc.
Überlegen Sie, was passieren würde, wenn sie Java-Floats entziehen. Libgdx (und Tausende anderer Bibliotheken und Programme) würden nicht funktionieren. Es wird eine Menge Mühe kosten, um alles auf den neuesten Stand zu bringen, möglicherweise Jahre für viele Projekte (schauen Sie sich nur den Übergang von Python 2 zu Python 3 an, der die Abwärtskompatibilität beeinträchtigt). Und nicht alles wird aktualisiert, manche Dinge werden für immer kaputt sein, weil die Betreuer sie aufgegeben haben, vielleicht früher als sie es getan hätten, weil es mehr Mühe kosten würde, als sie aktualisieren möchten, oder weil es nicht mehr möglich ist, das zu erreichen, was ihre Software angeblich war machen.
Performance
64-Bit-Doubles nehmen das Doppelte des Speichers in Anspruch und sind fast immer langsamer als 32-Bit-Floats (mit den seltensten Ausnahmen, bei denen die 32-Bit-Float-Fähigkeit so selten oder gar nicht verwendet wird, dass keine Optimierungsanstrengungen unternommen wurden) Solange Sie nicht für spezielle Hardware entwickeln, werden Sie dies in naher Zukunft nicht erleben.)
Libgdx ist eine Spielebibliothek, die für Sie besonders relevant ist. Spiele sind tendenziell leistungsempfindlicher als die meisten anderen Programme. Und Gaming-Grafikkarten (z. B. AMD Radeon und NVIDIA Geforce, nicht FirePro oder Quadro) weisen in der Regel eine sehr schwache 64-Bit-Gleitkomma-Leistung auf. Mit freundlicher Genehmigung von Anandtech finden Sie hier, wie die Leistung mit doppelter Präzision mit der Leistung mit einfacher Präzision bei einigen der besten verfügbaren Spielekarten von AMD und NVIDIA verglichen wird (ab Anfang 2016).
Beachten Sie, dass die Serien R9 Fury und GTX 900 neuer sind als die Serien R9 200 und GTX 700, sodass die relative Leistung für 64-Bit-Gleitkommazahlen abnimmt. Gehen Sie weit genug zurück und Sie werden die GTX 580 finden, die ein 1/8 Verhältnis wie die R9 200 Serie hatte.
1/32 der Leistung ist eine ziemlich große Strafe, die zu zahlen ist, wenn Sie einen engen Zeitrahmen haben und mit dem größeren Doppel nicht viel gewinnen.
quelle
Atomare Operationen
Zusätzlich zu dem, was andere bereits gesagt haben, besteht ein Java-spezifischer Nachteil von
double
(undlong
) darin, dass Zuweisungen zu primitiven 64-Bit-Typen nicht garantiert atomar sind . Aus der Java-Sprachspezifikation, Java SE 8 Edition , Seite 660 (Hervorhebung hinzugefügt):Yuck.
Um dies zu vermeiden, müssen Sie die 64-Bit-Variable mit dem
volatile
Schlüsselwort deklarieren oder eine andere Form der Synchronisierung für Zuweisungen verwenden.quelle
Andere Antworten scheinen einen wichtigen Punkt übersehen zu haben: Die SIMD- Architekturen können weniger / mehr Daten verarbeiten, je nachdem, ob sie mit
double
oder ohnefloat
Strukturen arbeiten (z. B. acht Gleitkommawerte gleichzeitig oder vier Doppelwerte gleichzeitig).Zusammenfassung der Leistungsaspekte
float
kann auf bestimmten CPUs (z. B. bestimmten Mobilgeräten) schneller sein.float
Benötigt weniger Speicher, so dass in großen Datenmengen der insgesamt erforderliche Speicher (Festplatte / RAM) und die verbrauchte Bandbreite erheblich reduziert werden können.float
Dies kann dazu führen, dass eine CPU weniger Strom verbraucht (ich kann keine Referenz finden, aber wenn dies nicht möglich ist, scheint dies zumindest plausibel zu sein).float
verbraucht weniger Bandbreite und ist in einigen Anwendungen von Bedeutung.float
Verwendet bis zu die Hälfte des Cache-Speichers im Vergleich zu doppelt.Zusammenfassung der Überlegungen zur Genauigkeit
float
reicht das ausdouble
hat sowieso viel mehr präzisionÜberlegungen zur Kompatibilität
double
(weil die GPU-Hersteller versuchen, die Anzahl der Grafikkerne zu erhöhen, und) Aus diesem Grund wird versucht, so viel Schaltkreise wie möglich in jedem Kern zu sparen. Durch die Optimierung fürfloat
können GPUs mit mehr Kernen erstellt werden.double
als internes Format akzeptiert werden (für 3D-Rendering-Vorgänge)Allgemeine Hinweise
double
Variablen auf dem Stack eine zusätzliche Präzision bietet (zusätzliche Präzision ohne Leistungseinbußen).float
jedoch möglicherweise nur begrenzte Wertedouble
).float
oder nurdouble
sehr hilfreich für den Compiler, um die Anweisungen zu simulieren.Weitere Informationen finden Sie in den Kommentaren von PeterCordes.
quelle
double
temporaries ist nur auf x86 mit der x87-FPU kostenlos, nicht mit SSE2. Das automatische Vektorisieren einer Schleife mitdouble
temporären Elementen bedeutet das Entpackenfloat
indouble
, für das eine zusätzliche Anweisung erforderlich ist, und Sie verarbeiten die Hälfte der Elemente pro Vektor. Ohne automatische Vektorisierung kann die Konvertierung normalerweise spontan während eines Ladens oder Speicherns erfolgen. Dies bedeutet jedoch zusätzliche Anweisungen, wenn Sie Floats und Doubles in Ausdrücken mischen.Abgesehen von den anderen genannten Gründen:
Wenn Sie Messdaten haben, seien es Drücke, Flüsse, Ströme, Spannungen oder was auch immer, wird dies häufig mit Hardware mit einem ADC durchgeführt.
Ein ADC hat normalerweise 10 oder 12 Bits, 14 oder 16 Bits sind seltener. Aber bleiben wir bei der 16-Bit-Version - wenn Sie im Vollbereich messen, haben Sie eine Genauigkeit von 1/65535. Das bedeutet, dass ein Wechsel von 65534/65535 zu 65535/65535 genau dieser Schritt ist - 1/65535. Das ist ungefähr 1.5E-05. Die Genauigkeit eines Schwimmers liegt um 1E-07, also viel besser. Sie verlieren also nichts, wenn Sie
float
diese Daten speichern.Wenn Sie übermäßige Berechnungen mit Schwebekörpern durchführen, ist die
doubles
Genauigkeit geringfügig schlechter als die von Schwebekörpern. Diese Genauigkeit wird jedoch häufig nicht benötigt, da es Ihnen oft egal ist, ob Sie nur eine Spannung von 2 V oder 2,00002 V gemessen haben Wenn Sie diese Spannung in einen Druck umwandeln, ist es Ihnen egal, ob Sie 3 bar oder 3,00003 bar haben.quelle