Wie beeinflußt man den Compiler so, daß er ohne Assemblercode die SSE und AVX Einheit effizient nutzt?
-
volkard schrieb:
Wo sollte man über mehr MMX, SSE oder so nachdenken? Also ich lese dauernd mulps. Dachte, damit sei der Kram in den alleimeisten Fällen schon für mich erledigt. Und ich müßte nur noch gelegentlich ins Compilat schauen, ob da oft genux mmx drin steht, und wenn's ein paar mal drinsteht, wird schon alles recht sein.
Also die Seite sagt dazu folgendes:
This doesn't show the function using inline Assembly. Anyone who is interested may read it in the demo project. Calculation times on my computer:
* C++ code - 26 ms
* C++ with SSE Intrinsics - 9 ms
* Inline Assembly with SSE instructions - 9 msExecution time should be estimated in the Release configuration, with compiler optimizations.
Obwohl also die SIMD Einheiten benutzt werden, kann man nicht davon ausgehen, daß der Compiler bei normalem C++ Code sie auch effizient zu nutzen weiß.
Das Ergebnis 26 ms vs. 9 ms ist schon erheblich.
-
Oder auch:
The program also calculates the minimum and maximum values in the result array. ARRAY_SIZE is defined as 100000. Result array is shown in the listbox. Calculation time (ms) for each way is shown in the dialog:
* C++ code - 6 ms on my computer;
* C++ code with SSE Intrinsics - 3 ms;
* Inline Assembly with SSE instructions - 2 ms.Assembly code performs better because of intensive using of the SSX registers. However, usually C++ code with SSE Intrinsics performs like Assembly code or better, because it is difficult to write an Assembly code which runs faster than optimized code generated by C++ compiler.
Der Code ist da:
http://www.codeproject.com/KB/recipes/sseintro.aspx
-
SIMD.this schrieb:
Also die Seite sagt dazu folgendes:
This doesn't show the function using inline Assembly. Anyone who is interested may read it in the demo project. Calculation times on my computer:
* C++ code - 26 ms
* C++ with SSE Intrinsics - 9 ms
* Inline Assembly with SSE instructions - 9 msExecution time should be estimated in the Release configuration, with compiler optimizations.
Das war am 10. Jul 2003...
Ich würde erstmal schauen, ob das noch so ist.
-
Zum GCC habe ich das hier gefunden:
http://ds9a.nl/gcc-simd/index.html
Das mit dem 2003 müßte mal testen, der Code ist ja da, nur komme ich jetzt nicht dazu. Freiwillige vor.
-
SIMD.this schrieb:
Aber für C gibt es wohl nichts vergleichbares, oder?
Es gibt da noch die Integrated Performance Primitives von Intel, was ungefähr deren Variante der SSE Intrinsics ist. Die müssten auch in C benutzbar sein, wenn ich mich nicht irre.
Ich weiß gerade nicht wie das mit der Lizenz ist, da musst du selber gucken. Intel ist recht interessiert daran, dass Programmierer ihre Prozessoren optimal ausnutzen, daher wird die Lizenz sicher frei oder zumindest nicht sehr restriktiv sein.
-
Da hat wohl einer schon die Arbeit gemacht:
Anderer dafür aktueller Test 2009 mit gcc 4.x und VS08:
Lately I have been playing a lot with SSE optimizations and I really enjoy it so far – using functions to tell the compiler what instructions to use makes you feel the power in your finger tips. At first I was naive and thought the compiler will do exactly what it’s being told, assuming that you know what you’re doing – looking at the SSE intrinsic header file was mostly a bunch of calls to internal GCC functions or ‘extern’ in MSVC, suggesting that the compiler will simply follow your leadership.
I assumed wrong – the compiler will take the liberty to optimized your code even further – at points you wouldn’t even think about, though I have noticed that is not always the case with MSVC. MSVC will sometimes behave too trusting at the coder even when optimizations obviously could be made. After grasping the concept of SSE and what it could do, I quickly realized MSVC won’t optimize as good as GCC 4.x or ICC would.
http://www.liranuna.com/sse-intrinsics-optimizations-in-popular-compilers/
-
Hier auch ganz interessant: http://www.g-truc.net/post-0369.html#menu
-
Wem das so wichtig ist, daß der Compiler extrem optimalen Code auf der CPU erzeugt, wird um den Intel-Compiler nicht herumkommen... also von Intel mal die Testversion laden, damit compilieren, und Benchmark machen.
Oder für die Rechenoperationen gleich eine entsprechende Bibliothek nehmen.
-
Marc++us schrieb:
Wem das so wichtig ist, daß der Compiler extrem optimalen Code auf der CPU erzeugt, wird um den Intel-Compiler nicht herumkommen...
Auf die Frage oben hin glaube ich das auch, aber...
http://developer.amd.com/tools/open64/Pages/default.aspx
http://developer.amd.com/sdks/AMDAPPSDK/Pages/default.aspx
http://developer.nvidia.com/cuda-downloads
-
... angeblich...
http://magazin.c-plusplus.net/artikel/Intel ISTEP 2011 Software Conference (Teil I)
Abschnitt "AMD und Intel"
-
Bestreitet keiner. Auch die dazuTools von Intel sind nicht so schlecht. Aber nur 30 Tage zum testen. Und danach? Was ich im Hinterkopf hatte, war etwa diese Richtung:
Erst diesen Thread gelesen...
http://www.c-plusplus.net/forum/287155?sid=43a79aa65747d6bdf241beaf652396d4...und sowas gedacht wie
http://www.heise.de/preisvergleich/a613014.html
(man bekommt zwei zum Preis von einer...)
-
Hiho!
Viele Compiler heutzutage besitzen AutoVectorizer, die genau dafuer gemacht sind! Damit der richtig gut arbeiten kann, ist es wichtig zu wissen dass deine Arrays nicht aliased sind! Leider ists fuer einen Compiler superschwer, das selbst rauszufinden.
Unter C gibts dafuer seit C99 das "restrict"-Keyword (http://en.wikipedia.org/wiki/Restrict). Ich wuerd davon ausgehen, dass du mit Hilfe von restrict deine Funktion einfach in reinem C schreiben kannst, und der AutoVectorizer wird optimalen SSE-Code draus basteln. Wichtig vllt. noch: achte darauf, dass deine Arrays auf Words aligned sind. Unaligned loads sind bei SSE-Einheiten schrecklich, schrecklich langsam (oder waren es zumindest 2009, als ich mich zuletzt damit befasst habe).
In C++ gibts leider kein "restrict" (mein groesster Kritikpunkt am neuen Standard
). Wie SeppJ schon gesagt hat, wird valarray dir vllt. helfen koennen, weil die Implementierungen dieser Klasse vermutlich Compiler-Spezifische Tricks und Erweiterungen verwenden, um die Wirkung von restrict zu erzielen.
Wenn du bereit bist, auf "Standard C++" zu verzichten und auf Compiler-Erweiterungen zurueckzugreifen: wie schon gsagt gibts SSE-Intrinsics, die gibts soweit ich weiss fuer mehrere Prozessoren, aber die sind doch ziemlich (EXTREM) low-level.
Besser gehts mit Compiler-Spezifischen Erweiterungen. Hier kann ich dir aber leider nur zum GCC Auskunft geben:
1. GCC kennt auch im C++ Modus "restrict" (IIRC)
2. Es gibt eine GCC-Erweiterung extra fuer sowas: http://gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Vector-Extensions.html (wichtig: du musst selbst dafuer sorgen, dass diese Vector-Datentypen im Speicher richtig aligned sind, sonst kanns sein dass du dir 'nen SegFault einfaengst (zumindest war das noch 2009 so, als ich damit rumgespielt hab))
-
BTW: bei MSVC gibt es
__declspec(restrict)
und__restrict
http://msdn.microsoft.com/en-us/library/8bcxafdh.aspx
http://msdn.microsoft.com/en-us/library/5ft82fed.aspx