32-bit-oder 64-bit-floating-point-performance
Habe ich lief in einem kuriosen problem. Ein Algorithmus, an dem ich arbeite besteht aus vielen Berechnungen wie diese
q = x(0)*y(0)*z(0) + x(1)*y(1)*z(1) + ...
wobei die Länge der Summe zwischen 4 und 7.
Den ursprünglichen Berechnungen erfolgen mit 64-bit-Präzision. Für Experimente, versuchte ich mit 32-bit-Genauigkeit für x -, y -, z-input-Werte (so dass die Berechnungen werden durchgeführt unter Verwendung der 32-bit), und speichern endgültige Ergebnis als 64-bit-Wert (einfache Besetzung).
Ich erwartete 32-bit-Leistung besser zu sein (cache-Größe, SIMD Größe, etc.), aber zu meiner überraschung gab es keinen Unterschied in der Leistung, vielleicht sogar sinken.
Der Architektur in Frage, Intel 64, Linux, und GCC. Beide codes tun scheinen SSE und arrays in beiden Fällen orientieren sich an 16-byte-Grenze.
Warum wäre es so? Meine Vermutung bisher ist, dass 32-bit-Genauigkeit verwenden können, SSE nur auf die ersten vier Elemente, der rest erfolgt Seriell verstärkt durch Darsteller overhead.
- Sie habe ein Kopfgeld - was hat Euch nicht gefallen über dsimcha Antwort? Es könnte auch einen Versuch Wert, die neueste GCC-Sie können oder Intel-compiler software.intel.com/en-us/articles/..., um zu sehen, wenn Sie tun, einen besseren job zu kompilieren / vectorising.
- Ich mag seine Antwort, dennoch möchten, dass andere Meinungen auch, so dass ich ein Kopfgeld
Du musst angemeldet sein, um einen Kommentar abzugeben.
Auf x87 zumindest, alles ist wirklich in 80-bit-Genauigkeit intern. Die Präzision wirklich nur bestimmt, wie viele der bits im Speicher gespeichert werden. Dies ist Teil der Grund, warum verschiedene Optimierungs-Einstellungen ändern können Ergebnisse leicht: ändern Sie die Höhe der Rundung von 80-bit -, 32 - oder 64-bit.
In der Praxis, mit 80-bit floating point (
long double
in C und C++real
in D) ist in der Regel langsam, weil es keine effiziente Weise zu laden und speichern von 80 bits aus dem Speicher. 32 - und 64-bit sind in der Regel gleich schnell, vorausgesetzt, dass die Speicherbandbreite ist nicht der Engpass, d.h. wenn alles im cache jedenfalls. 64-bit kann langsamer sein, wenn eine der folgenden passiert:Soweit SIMD-Optimierungen gehen, es sollte angemerkt werden, dass die meisten Compiler sind schrecklich auf der auto-Vektorisieren-code. Wenn Sie nicht möchten, schreiben Sie direkt in Assembler-Sprache, der beste Weg, um die Vorteile dieser Anweisungen ist die Verwendung Dinge wie array-Weise Operationen, die verfügbar sind, zum Beispiel, in D, und implementiert, der SSE-Anweisungen. Ähnlich wie in C oder C++, würden Sie wahrscheinlich wollen, um eine high-level-Bibliothek von Funktionen, die SSE-optimiert, obwohl ich nicht weiß, eine gute aus der Spitze von meinem Kopf, weil ich meist Programm in D.
Es ist wahrscheinlich, weil dein Prozessor macht immer noch die 64bit-zählen und dann die trimms Nummer. Es gab einige CPU-flag könnte man ändern, aber ich kann mich nicht erinnern...
Überprüfen Sie zuerst die ASM, das wird produziert. Es kann nicht sein, was Sie erwarten.
Versuche auch, es zu schreiben, als eine Schleife:
Einige compiler vielleicht feststellen, die Schleife und nicht die ent-form.
Schließlich, Ihr code verwendet
()
eher als[]
. Wenn Ihr code viele Funktionsaufrufe (12 bis 21), die Sumpf-die FP-Kosten und auch das entfernen der fp-Berechnung, alle zusammen, nicht viel Unterschied. Inlineing OTOH könnte.q()
sind Makros konvertieren direkt in das raw-pointer-Zugriff