Führt die Durchführung komplexer Multiplikationen und Divisionen durch SSE-Anweisungen einen Vorteil? Ich weiß, dass Addition und Subtraktion besser sind, wenn SSE verwendet wird. Kann mir jemand sagen, wie ich mit SSE komplexe Multiplikationen durchführen kann, um bessere Ergebnisse zu erzielen?
Well komplexe Multiplikation ist definiert als:
%Vor%Ihre 2 Komponenten in einer komplexen Zahl wären also
%Vor%Angenommen, Sie verwenden 8 Gleitkommazahlen, um 4 komplexe Zahlen darzustellen, die wie folgt definiert sind:
%Vor%Und wenn Sie gleichzeitig (c1 * c3) und (c2 * c4) machen möchten, würde Ihr SSE-Code wie folgt aussehen:
(Hinweis: Ich habe MSVC unter Windows verwendet, aber das Prinzip wird gleich sein).
%Vor%Was ich oben gemacht habe, ist, dass ich die Mathematik etwas vereinfacht habe. Nehmen wir Folgendes an:
%Vor%Durch Umordnen habe ich die folgenden Vektoren
%Vor%Ich multipliziere dann 0 und 2, um zu erhalten:
%Vor%Als nächstes multipliziere ich 3 und 1 zusammen, um zu erhalten:
%Vor%Schließlich drehe ich die Zeichen von ein paar der Schwimmer in 3
%Vor%Also kann ich sie zusammenfügen und bekomme
%Vor%Was wir wollten:)
Nur der Vollständigkeit halber, das Intel® 64 und IA-32 Architectures Optimization Reference Manual, das heruntergeladen werden kann hier enthält Assemblierung für komplexe Multiplikation (Beispiel 6-9) und komplexe Division (Beispiel 6-10).
Hier ist zum Beispiel der Multiplikationscode:
%Vor% Die Assembly ist direkt mit gccs X86 verknüpft intrinsics (projezieren Sie einfach jede Anweisung mit __builtin_ia32_
).
Der Algorithmus in der Intel Optimierungsreferenz behandelt Überläufe und NaN
s in der Eingabe nicht richtig.
Ein einzelner NaN
im Real- oder Imaginärteil der Zahl wird fälschlicherweise auf den anderen Teil verteilt.
Da mehrere Operationen mit Unendlichkeit (z. B. unendlich * 0) in NaN
enden, können Überläufe dazu führen, dass NaN
s in Ihren ansonsten gut ertragenen Daten erscheint.
Wenn Überläufe und NaN
s selten sind, können Sie das einfach vermeiden, indem Sie im Ergebnis auf NaN
prüfen und sie mit der IEEE-kompatiblen Compiler-Implementierung neu berechnen: