Wenn die Assembly-Ausgabe des folgenden Codes angezeigt wird (keine Optimierungen, erzeugen -O2 und -O3 sehr ähnliche Ergebnisse):
%Vor%GCC tut etwas, was mir schwer fällt:
%Vor%Warum verschiebt GCC die Float-Werte zweimal in xmm0 und xmm1 und führt auch zweimal ucomiss aus?
Wäre es nicht schneller, folgendes zu tun?
%Vor%Ich bin überhaupt kein richtiger Assembler, aber es schien mir komisch, doppelte Anweisungen zu haben. Gibt es ein Problem mit meiner Version des Codes?
Aktualisieren
Wenn Sie das volatile, das ich ursprünglich hatte, entfernen und durch scanf () ersetzen, erhalten Sie die gleichen Ergebnisse:
%Vor%Und der entsprechende Assembler:
%Vor%Endgültiges Update
Nachdem wir einige der folgenden Kommentare gelesen haben, scheint Han (der unter Jonathan Lefflers Post kommentierte) dieses Problem zu lösen. GCC macht die Optimierung nicht, weil es nicht möglich ist, sondern weil ich es nicht gesagt habe. Es scheint, dass alles auf IEEE-Gleitkommaregeln beruht und die strengen Bedingungen zu erfüllen GCC kann nicht einfach einen Sprung machen, wenn oberhalb oder unterhalb der ersten UCOMISS springen, weil es alle speziellen Bedingungen von Gleitkommazahlen zu behandeln hat. Bei der Verwendung der han-Empfehlung des -ffast-math-Optimizers (keine der -Ox-Flags ermöglicht -fast-math, da es einige Programme kaputt machen kann) macht GCC genau das, wonach ich gesucht habe:
Die folgende Baugruppe wurde mit GCC 4.3.2 "gcc -S -O3 -ffast-math test.c"
erstellt %Vor%Beachten Sie, dass die beiden UCOMISS-Anweisungen nun durch einen COMISS direkt gefolgt von einem JA (springe wenn darüber) und JB (springe wenn darunter) ersetzt werden. GCC ist in der Lage, diese Optimierung zu nageln, wenn Sie es -ffast-math verwenden!
UCOMISS gegen COMISS (http://www.softeng.rl.ac.uk/st/archive/SoftEng/SESP/html/SoftwareTools/vtune/users_guide/mergedProjects/analyzer_ec/mergedProjects/reference_olh/mergedProjects/instructions/instruct32_hh /vc315.htm): "Der UCOMISS-Befehl unterscheidet sich vom COMISS-Befehl dadurch, dass er eine ungültige SIMD-Gleitkommaausnahme nur signalisiert, wenn ein Quelloperand ein SNaN ist. Der COMISS-Befehl signalisiert ungültig, wenn ein Quelloperand entweder ein QNaN oder ein ist SNaN. "
Nochmals vielen Dank für die hilfreiche Diskussion.
Hier ist ein anderer Grund:
Wenn du es dir genau ansiehst, ist es NICHT derselbe Ausdruck.
Sie sind keine Komplemente voneinander. Daher müssen Sie trotzdem zwei Vergleiche durchführen. volatile
erzwingt das erneute Laden der Werte.
EDIT: (siehe Kommentare, ich habe vergessen, dass du das mit den Flags machen kannst)
Um die neue Frage zu beantworten:
Die Kombination der beiden ucomiss
ist keine vollständig offensichtliche Optimierung aus der Sicht des Compilers.
Um sie zu kombinieren, muss der Compiler:
ucomiss %xmm0, %xmm1
das gleiche ist wie ucomiss %xmm1, %xmm0
. All dies muss getan werden nachdem der Compiler die Befehlsauswahl vornimmt. Und die meisten Optimierungsdurchläufe werden vor der Befehlsauswahl durchgeführt.
Was mich mehr beunruhigt ist, warum f1
und f2
nicht in Registern gehalten werden, nachdem Sie volatiles
losgeworden sind. -O3
gibt dir das wirklich?
Das volatile
-Qualifikationsmerkmal bedeutet, dass sich die Werte von f1
und f2
möglicherweise so ändern, wie der Compiler es nicht erkennt / erwartet. Daher muss es jedes Mal auf den Speicher zugreifen, wenn es f1
oder f2
verwendet. Der generierte Code macht das - so ist es korrekt.
Vergleichen und kontrastieren Sie mit dem Code, den Sie erhalten, wenn Sie die volatile
-Qualifikatoren von einer der Variablen oder beiden Variablen entfernen. Möglicherweise müssen Sie die Werte von f1
und f2
von irgendwo lesen, um zu vermeiden, dass der Compiler die Ausdrücke zum Zeitpunkt der Kompilierung auswertet.
Im aktualisierten Code erhalten Sie zwei verschiedene Beschwörungsformeln für die Anweisung ucomiss
, obwohl die vorhergehenden Anweisungen movss
identisch sind:
Die Reihenfolge der Operanden für die Anweisung ucomiss
ist für die umgekehrte Bedingung umgekehrt:
Ich bin nicht davon überzeugt, dass der Optimierer dort optimiert, wo es möglich ist, aber die Frage ist, dass sich meine Frage über mein Fachwissen hinaus verändert.