Hallo Zusammen,
beim optimieren einer Funktion zum Finden von Minimum und Maximum ist
mir aufgefallen, dass -ffast-math die Geschwindigkeit des Codes um ca.
Faktor 10 steigert. Der erzeugte Assembler-code wirft jedoch einige
fragen auf:
http://goo .gl/EhxsaN (Leerzeichen entfernen, sonst spam) so auf den
ersten Blick schaut das nach partiellem loop unrolling aus, scheint aber
ein bisschen mehr dabei zu sein. Ohne -ffast-math ist Assembler-Code
deutlich kürzer aber eben auch um Faktor 10 langsamer. Was für eine
anscheinend doch sehr effiziente Optimierung hat hier zugeschlagen? Der
mit -ffast-math erzeugte code schafft es dann auch die
Speicherbandbreite der CPU vollständig auszulasten.
Lukas
Lukas K. schrieb:> Jep, kannste bei dem angegebenen Link einfach ausprobieren.
Sicher nicht. Erste Internet-Grundregel: du sollst nicht auf dubiose
Links klicken.
Oliver
Lukas K. schrieb:> Was für eine> anscheinend doch sehr effiziente Optimierung hat hier zugeschlagen?
An GCC wird seit fast 30 Jahren gearbeitet. Man muss davon ausgehen,
dass nicht mal die GCC-Maintainer über jedes Detail Bescheid wissen. Bei
solchen Details ist die einzige Dokumentation häufig der Source-Code.
https://gcc.gnu.org/wiki/FloatingPointMath
enthält ein paar grundlegende Erklärungen, aber nicht die exakten
Optimierungs-Algorithmen die verwendet werden. Wenn ich es richtig
verstehe sind nicht nur der Compiler, sondern auch die Libraries an
fast-math beteiligt. Was bedeutet, man müsste nicht nur im
Compiler-Sourcecode, sondern noch in den Libraries nach den
Optimierungen suchen.
Dann kommt hinzu, dass alle Optimierungen von der Target-Architektur
abhängen. Wie du aus dem Link ersehen kannst, hängen die Optimierungen
auch noch gegenseitig voneinander ab.
Lukas K. schrieb:> Was für eine> anscheinend doch sehr effiziente Optimierung hat hier zugeschlagen?
Der Kern bei grossem <n> ist nicht in klassischem Sinn unrolled, sondern
über AVX vektorisiert.
Langsame Version, 32 Bits am Stück:
Lukas K. schrieb:> Aber schon beeindruckend, was ein> moderner Compiler da schafft. Hätte ich in ASM niemals hinbekommen.
Wird einfacher wenn du davon ausgehen darfst, dass die Daten auf 32
Bytes aligned sind und n durch 8 teilbar ist. Ein erheblicher Teil des
Codes hat damit zu tun, dass dies hier nicht garantiert ist.
Mit AVX-512 ändert sich das dann freilich wieder. Sowas überlässt man
auch deshalb lieber dem Compiler.
Lukas K. schrieb:> erst mit -ffast-math macht, müssen dazu Umformungen gemacht werden, die> zu Ungenauigkeiten führen können.
Möglicherweise ist das Schema dieser Vektorisierung nicht speziell an
die Eigenschaften von min/max angepasst, sondern wird auch auf andere
Vektoroperationen analoger Bauweise angewandt, bei denen das exakte
Ergebnis von der Reihenfolge der Rechnungen abhängt, wie etwa bei einer
Summe.