Single versus Double Floating-Point-Präzision

13

Gleitkommazahlen mit einfacher Genauigkeit belegen die Hälfte des Arbeitsspeichers und können auf modernen Maschinen (auch auf GPUs) fast doppelt so schnell ausgeführt werden wie mit doppelter Genauigkeit. Viele FDTD-Codes, die ich gefunden habe, verwenden ausschließlich Arithmetik und Speicherung mit einfacher Genauigkeit. Gibt es eine Faustregel, wann es akzeptabel ist, einfache Genauigkeit zum Lösen von spärlichen Gleichungssystemen im großen Maßstab zu verwenden? Ich gehe davon aus, dass es stark von der Matrixbedingungsnummer abhängen muss.

Darüber hinaus gibt es eine wirksame Technik, bei der bei Bedarf doppelte Genauigkeit und bei der keine doppelte Genauigkeit erforderlich ist. Zum Beispiel würde ich denken, dass es für eine Matrixvektormultiplikation oder ein Vektorpunktprodukt eine gute Idee sein könnte, die Ergebnisse in einer Variablen mit doppelter Genauigkeit zu akkumulieren (um Löschfehler zu vermeiden), aber dass einzelne Einträge miteinander multipliziert werden kann mit einfacher Genauigkeit multipliziert werden.

Ermöglichen moderne FPUs nahtlos die Umstellung von einfacher Präzision (Float) auf doppelte Präzision (Double) und umgekehrt? Oder sind diese kostspieligen Operationen?

Costis
quelle

Antworten:

7

Für alle nicht-trivialen Probleme (dh für diejenigen, bei denen die Leistung von Bedeutung ist) befindet sich fast der gesamte Speicher in der Matrix und relativ wenig in Vektoren. Beispiel: Bei 3D-Taylor-Hood-Elementen für die Stokes-Gleichung befinden sich einige hundert Elemente pro Zeile in der Matrix, und dies überwiegt bei weitem die für Vektoren erforderliche Speicherkapazität. Wir haben also mit der Idee gespielt, die Matrix als Floats und die Vektoren als Doubles zu speichern. Ich kann mich nicht an unsere Timing-Ergebnisse erinnern, aber ich bin mir sicher, dass wir keine Probleme mit der Abrundung usw. gesehen haben. Dieser Ansatz funktioniert also auf jeden Fall.

Wolfgang Bangerth
quelle
Vielen Dank, Prof. Bangerth. Was ist mit iterativen Matrixlösern? Skalieren Sie für die Matrix-Vektor-Produkte auf doppelte Genauigkeit oder skalieren Sie die Vektorelemente für die Multiplikationen auf Einfach und für die Akkumulation auf Doppel?
Costis
Ich habe natürlich über iterative Löser gesprochen. Wir machen alle Vektoren in doppelter Genauigkeit (weil es keine Rolle spielt), also geschieht die Operation dst = matrix src als double = float double. Die Akkumulation geschieht dann in doppelter Präzision, aber ich wäre wirklich sehr überrascht, wenn es überhaupt darauf ankam.
Wolfgang Bangerth
Irgendwo da draußen (seit vielleicht zwei Jahrzehnten) gibt es ein Papier, das angibt, dass die Punktprodukte mit einer höheren Genauigkeit als der doppelten Genauigkeit hergestellt werden sollten. Ich habe die Referenz nicht zur Hand, aber ich werde später nachsehen, ob ich sie finden kann.
Bill Barth
Ja, das würde mich nicht überraschen. Das passt auch zu dem, was wir tun.
Wolfgang Bangerth
Sie verwenden Quad-Präzision für Punktprodukte? Wenn ja, cool! Ich hatte nicht gehört, dass jemand dies in einer Bibliothek tat.
Bill Barth
3

Mein Rat wäre, sich hauptsächlich auf den Speicherverbrauch zu konzentrieren, um zu entscheiden, wann die einfache Genauigkeit (Float) verwendet wird. Die Massendaten für eine FDTD-Berechnung sollten also float verwenden, aber ich würde die Problembeschreibung selbst (wie Geometrie, Materialparameter, Anregungsbedingungen) und alle zugehörigen Metadaten doppelt verwenden.

Ich würde alle Performance unkritisch halten und nicht tief analysierte Berechnungen doppelt durchführen. Insbesondere würde ich polygonale Daten und andere Beschreibungen der Geometrie doppelt halten (wenn möglich sogar ganzzahlig), da die Erfahrung zeigt, dass Sie die rechnerischen geometrischen Teile Ihres Codes niemals vollständig robust machen werden, selbst wenn dies theoretisch möglich wäre.

Ein dritter Teil, den ich im Doppelten behalten möchte, sind analytische Berechnungen, einschließlich Verknüpfungen mit nicht symmetrischen Eigenwertzerlegungen. Als Beispiel habe ich eine stückweise definierte rotationssymmetrische 2D-Funktion und ich brauche ihre Fourier-Transformation. Es gäbe verschiedene numerische Möglichkeiten, die FFTs und geeignete "analytische Tiefpassfilter" umfassen, um sie "effizient" zu erhalten. Da die Leistung unkritisch ist, habe ich stattdessen einen "exakten" analytischen Ausdruck mit Bessel-Funktionen verwendet. Da dies zunächst eine Abkürzung war und ich keine Zeit darauf verwenden werde, die Fehlerausbreitung meiner komplizierten Formel zu analysieren, verwende ich für diese Berechnung besser die doppelte Genauigkeit. (Es stellte sich immer noch heraus, dass nur einige der analytisch äquivalenten Ausdrücke für die Formel verwendbar waren.)

Thomas Klimpel
quelle