SSE store
-
Ausschnitt aus: RGB nach HSVpolar
Michael
-
was für ne library benutzt du da? ist das sse oder 3dnow? ich vermut mal sse (wg. topic)
wo kann man die library runterladen...?
-
Ist SSE;
Du brauchst nichts herunterzuladen. Das sind Compiler-intrinsics.
Wird u.a. von gcc, msvc++, icc unterstützt.#include <xmmintrin.h> bzw. <emmintrin.h> reicht.
Michael
-
Hmm, schau mal nach, ob der Code anders ausschaut, wenn du das store dazugibts. Vielleicht gehen dem Compiler dann irgendwie die Register aus.
-
nt
-
Was heißt 'nt'?
-
nt = no text
in diesem forum kann man ja nicht löschen...
kannst du den algorithmus mal in normalem c++ ohne intrinsics zeigen? einiges hier sieht ein bisschen suspekt aus. einen so dramatischen geschwindigkeits unterschied kann ich im übrigen hier nicht feststellen - welchen compiler/welche cpu hast du?
-
Kein Problem, ich werde mal was vorbereiten, das Du testen kannst....
Aber zunächst möchte ich mein Problem eingrenzen:
Am Ende der Berechnung in der Schleife wird das Ergebnis einer Multiplikation in der Variablen xs gespeichert.
Wenn ich diese Variable mit store in ein float[4] Array(aligned) speichern will dauert das eine Ewigkeit; speichere ich jedoch z.b. xs=_mm_setzero_ps() bleibt die hohe Geschwindigkeit erhalten.Vieleicht kann jemand damit was anfangen(aus nem Profiler). Erst kommt die Intrinsic Methode, dann der Assemblercode, den der Compiler daraus gemacht hat.(leider kann ich selbst nicht wirklich Assembler)
xs=_mm_mul_ps(xd,xa); mulps xmm0, xmm2 _mm_store_ps(inp_sse1,xs); movaps XMMWORD PTR [eax], xmm0 jnz Extract+1a0 mov edi, DWORD PTR [esp+02ch] mov ecx, DWORD PTR [ebp+0ch] add DWORD PTR [esp+01ch], ecx sub DWORD PTR [esp+020h], 01h jnz Extract+160
Ich benutze den msvc++7.1 Compiler. Getestet ist das auf einem Pentium M, einem AthlonXP und einem P4HT.
Falls sich jemand über die undurchsichtigen Variablennamen wundert:
nach meinen Tests ist SSE nur dann schnell, wenn ich auf Variablen arbeite, die auf dem Stack der jeweiligen Methode liegen. Bei allem, was was sonst irgendwo auf dem heap liegt, ist load/store viel zu langsam..
Und ich will nur wenige Variablen, da diese bei jedem Methodenaufruf angelegt werden müssen...Gruß
Michael
-
hmm...täusch ich mich, oder sind das stinknormale assembler befehle?
sollten da nicht irgendwelche SSE teile kommen?//edit ahso, is schon ok
-
[..]
msvc++ 7.1 Compiler; release;
kompiliert mit:
/O2 /Ot /G7 /I "D:\test" /D "WIN32" /D "NDEBUG" /D "_MBCS" /FD /EHsc /MT /GS /arch:SSE /Fo"Release/" /Fd"Release/vc70.pdb" /W3 /nologo /c /Zi /TP//EDIT Hat sich erledigt! Es sieht so aus, dass der Compiler die SSE Befehle durch die eingeschalteten Optimierungsfunktionen eliminiert, weil nicht mehr auf das Ergebniss zugegriffen wird!
Ist ohne Warnung des Compilers aber eine besonders schlechte Optimierungsstrategie. Ob der gcc auch auch einem Mist macht???Gruß
Michael
-
hab keinen intel, und sse läuft doch nur auf intel, oder?
-
//EDIT s.u.
-
ne das läuft auch auf amd athlon xp cpu's.
-
lokale xmm variable, werden, wenn möglich, direkt auf register gemappt und nicht auf dem stack angelegt (das geht immer dann, wenn die funktion selbst keine andren funktionen (ausser intrinsics) aufruft und man nicht auf die komponenten der xmm variable zugreifen muss). daher der geschwindigkeits vorteil.
ich bin aber fast sicher, dass diese funktion nicht das macht, was sie soll (daher die bitte um normalen c++ quelltext) - ich habs hier mal hinzugefügt:
inp_sse1[0]=data[y]; // red inp_sse1[1]=data[y+1]; // green inp_sse1[2]=data[y+2]; // blue inp_sse1[3]=0; // 0 xa = _mm_load_ps(inp_sse1); // 0, blue, green, red xb = _mm_load_ps(inp_sse2); // .39, .39, .39, .39 xc = _mm_mul_ps(xa, xb); // 0, blue*.39, green*.39, red*.39 - *.39 im folgenden weggelassen xa=_mm_shuffle_ps(xc,xc,1); // red, red, red, green xb=_mm_shuffle_ps(xc,xc,2); // red, red, red, blue xa=_mm_max_ps(_mm_max_ps(xc , xa),xb ); // red, max(red,blue), max(red,green), max(red,green,blue) xb=_mm_min_ps(_mm_min_ps(xc , xa),xb ); // 0, red, red, min(red,blue) xs=_mm_sub_ss(xa,xb); // red, max(red,blue), max(red,green), max(red,green,blue)-min(red,blue) xs=_mm_div_ss(xs,xa); // red, max(red,blue), max(red,green), 1-min(red,blue)/max(red,green,blue) xd=_mm_div_ps(xb,xa); // 0, red/max(red,blue), red/max(red,green), min(red,blue)/max(red,green,blue), xa=_mm_movelh_ps(xs,xs); // max(red,green), 1-min(red,blue)/max(red,green,blue), // max(red,green), 1-min(red,blue)/max(red,green,blue) xs=_mm_mul_ps(xd,xa); _mm_store_ps(out_sse,xs); //!!
-
Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum Rund um die Programmierung verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Dieser Thread wurde von Moderator/in kingruedi aus dem Forum Rund um die Programmierung in das Forum Assembler verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Zunächst mal, danke für die Mühe die Du Dir mit meinem Problem gemacht hast.
Es scheint mit aber so zu sein, das die Funktionen garnicht aufgerufen werden, wenn ich das Store nicht an das Ende der Berechnung stelle.(sieht im Profiler so aus) Im grunde ist das auch richtig, denn wenn ich das Ergebniss nicht weiter verwende kann der Compiler die berechnung auch weglassen....
Wenn ich da falsch liege, bitte ich um Berichtigung, wäre wichtig.Desweiteren war die Methode nur ein Ausschnitt der vollständigen Version;
aber darin war mein Problem ebenfalls vorhanden..Ich hab zum testen mal was hier hingelegt:
http://www.uni-koblenz.de/~mmayer/testSSE.cpp
(der V Kanal im HSV-Farbraum wird mit Absicht weggelassen)Danke
Gruß
Michael
-
hmm.. mal ne dumme frage..
funktioniert das ausrichten des outputarrays eigentlich? bei mir wird der befehl zum ausrichten einfach ignoriert.. wenn das nicht funktioniert könnte ein ... sagen wir mal ein bruchteil deiner 600% leistungsverlust darauf zurück geführt werden.
(wenn die bib so schlau ist unausgerichtete speicheradressen mit movups anzusprechen).
ausserdem hatte ich diese leistungsschwankungen auch bei meinen "optimierten" programmen. meistens war es auf unnötige konstruktoraufrufe zurückzuführen. womöglich auch auf den statuswechsel, von normaler fpu -> sse. das soll angeblich (aus intel/amd seite so zu hören) keine zeit mehr kosten.
im zweifelsfall schreib das doch ganz zu nem assembler block um
dann kannst du wenigstens kontrollieren was genau da passiert.. (und es mit dem vom compiler erzeugten code vergleichen compileroption -S).gruss
eviluser
-
Eigentlich wollte ich dem Compiler ja so viel arbeit wie möglich überlassen; deshalb intrinsics, da kann der Compiler z.B. die Register selbst auswählen.
Ich habe auch irgendwie das Gefühl, dass die Ausrichtung eher nach dem Zufallsprinzip stattfindet.
Und eigentlich habe ich alles probiert;
_aligned_malloc, __declspec(align ; heap oder stack. 100% hats nie funktioniert.Vielleicht klappts ja noch..aber 2 Monate wollte ich nicht daran sitzen.. :-))))
Gruß
Michael
-
hehe.. schau mal nach meinen threads
mit dem problem hab ich mich auch schon beschäftigt..
die bisher sicherste lösung war die von camper:
float *p = (float*) malloc(grösse*sizeof(float)+15), *p_aligned; p_aligned = (float*) (((unsigned)p+15)&-16); //tu was mit p_aligned free(p);
gruss
eviluser