Können wir bei zwei verschiedenen BLAS-Implementierungen erwarten, dass sie exakt dieselben Gleitkommaberechnungen durchführen und dieselben Ergebnisse zurückgeben? Oder kann es beispielsweise vorkommen, dass man ein Skalarprodukt als und eines als ( x 1 y 1 + x 2 y berechnet 2 ) + ( x 3 y 3 + x 4
also möglicherweise abweichendes Ergebnis bei IEEE-Gleitkomma-Arithmetik?
floating-point
blas
Federico Poloni
quelle
quelle
Antworten:
Nein, das ist nicht garantiert. Wenn Sie einen NETLIB BLAS ohne Optimierungen verwenden, stimmen die Ergebnisse größtenteils überein. Für jede praktische Anwendung von BLAS und LAPACK wird jedoch ein hochoptimiertes paralleles BLAS verwendet. Die Parallelisierung bewirkt, auch wenn sie nur in den Vektorregistern einer CPU parallel arbeitet, dass sich die Reihenfolge, in der die einzelnen Terme ausgewertet werden, und die Reihenfolge der Summierung ändert. Nun folgt aus der fehlenden assoziativen Eigenschaft im IEEE-Standard, dass die Ergebnisse nicht gleich sind. Genau das, was Sie erwähnt haben, kann passieren.
In der NETLIB BLAS ist das Skalarprodukt nur eine um den Faktor 5 abgewickelte for-Schleife:
und es liegt an dem Compiler, ob jede Multiplikation sofort zu DTEMP hinzugefügt wird oder ob alle 5 Komponenten zuerst aufsummiert werden und dann zu DTEMP hinzugefügt werden. In OpenBLAS handelt es sich je nach Architektur um einen komplizierteren Kernel:
Dadurch wird das Skalarprodukt in kleine Skalarprodukte der Länge 4 aufgeteilt und summiert.
Bei Verwendung der anderen typischen BLAS-Implementierungen wie ATLAS, MKL, ESSL, ... bleibt dieses Problem gleich, da jede BLAS-Implementierung unterschiedliche Optimierungen verwendet, um schnellen Code zu erhalten. Aber meines Wissens braucht man ein künstliches Beispiel, um wirklich fehlerhafte Ergebnisse zu erzielen.
Wenn es notwendig ist, dass die BLAS-Bibliothek für die gleichen Ergebnisse zurückgibt (bitweise gleich), muss eine reproduzierbare BLAS-Bibliothek verwendet werden, wie zum Beispiel:
quelle
Die kurze Antwort
Wenn die beiden BLAS-Implementierungen so geschrieben sind, dass die Operationen in genau derselben Reihenfolge ausgeführt werden, und die Bibliotheken mit denselben Compiler-Flags und demselben Compiler kompiliert wurden, erhalten Sie dasselbe Ergebnis. Fließkomma-Arithmetik ist nicht zufällig, sodass zwei identische Implementierungen zu identischen Ergebnissen führen.
Es gibt jedoch eine Vielzahl von Dingen, die dieses Verhalten aus Gründen der Leistung stören können ...
Die längere Antwort
IEEE gibt außerdem die Reihenfolge an, in der diese Vorgänge ausgeführt werden, und legt fest , wie sich die einzelnen Vorgänge verhalten sollen. Wenn Sie jedoch Ihre BLAS-Implementierung mit Optionen wie "-ffast-math" kompilieren, kann der Compiler Transformationen ausführen, die in exakter Arithmetik wahr, in IEEE-Gleitkommazahlen jedoch nicht "korrekt" sind. Das kanonische Beispiel ist die Nichtassoziativität der Gleitkommazugabe, wie Sie betont haben. Bei aggressiveren Optimierungseinstellungen wird Assoziativität vorausgesetzt, und der Prozessor erledigt so viel wie möglich parallel, indem er die Operationen neu anordnet.
quelle
if (x == 0) assert(x == 0)
es manchmal scheitern, was aus einer bestimmten Sicht so gut wie zufällig ist.if (x != 0) assert(x != 0)
wegen der erweiterten Genauigkeit der Arithmetik sein.Im Allgemeinen nicht. Abgesehen von der Assoziativität kann die Auswahl von Compiler-Flags (z. B. Aktivierung von SIMD-Befehlen, Verwendung von Fused Multiply Add usw.) oder der Hardware (z. B. Verwendung von Extended Precision ) zu unterschiedlichen Ergebnissen führen.
Es gibt einige Anstrengungen, um reproduzierbare BLAS-Implementierungen zu erhalten. Weitere Informationen finden Sie unter ReproBLAS und ExBLAS .
quelle