Frage zu SSE Befehl
-
Hallo zusammen
Ich versuche gerade, eine Matrizenmultiplikation mit Hilfe des SSE Befehlssatz zu implementieren, aber irgendwie kriege ich die Werte nicht korrekt in die Register.Ich habe ein Row-Major Matrix. Für die Multiplikation muss ich ja IMHO im ersten Register jeweils eine Zeile der ersten Matrix und im zweiten Register die entsprechende Spalte der zweiten Matrix haben. Aber wie kriege ich das hin? Wie kriege ich die Spalte einer Matrix (Row-Major Order) in ein einzelnes xmm register?
Das Problem ist ja auch, dass ich die ganzen (Un)pack befehle nicht benutzten kann, weil der Abstand im Speicher zwischen den einzelnen Werten einer Spalte zu gross ist. Geht das überhaupt mit einem einzelnen Befehl oder muss ich jeden einzelnen Wert einer Spalte zuweisen und falls ja, mit welchem Befehl movss kopiert ja immer nur die untersten 32-bit?
Macht es vielleicht Sinn, eine der Matrizen vorher zu transponieren ? Dann wäre sie ja dann IMHO Column-Major.
Mfg Samuel
-
Das beantwortet zwar deine Frage nicht, aber wenn du nur ein Matrix-Produkt möglichst schnelle bekommen willst, solltest du einfach BLAS (ATLAS oder sonst, wenn du es dir leisten kannst, die Intel MKL) verwenden. Es gäbe da auch noch als etwas anderen Ansatz liboil.
-
Ishildur schrieb:
Das Problem ist ja auch, dass ich die ganzen (Un)pack befehle nicht benutzten kann, weil der Abstand im Speicher zwischen den einzelnen Werten einer Spalte zu gross ist.
Verstehe ich nicht. Sofern die Dimensionen es zulassen, würde ich jeweils 4 Zeilen des einen Faktors in Register laden, dort transponieren (so dass jedes Register eine Spalte enthält) und dann jeweils mit den Zeilen des anderen Faktos multiplizieren und ins Ergebnis schreiben. Und für dieses Transponieren sind die unpack-Befhele gut geeignet.
-
Ishildur schrieb:
Hallo zusammen
Ich versuche gerade, eine Matrizenmultiplikation mit Hilfe des SSE Befehlssatz zu implementieren, aber irgendwie kriege ich die Werte nicht korrekt in die Register.Ich frag mich, wieso wohl nicht - Beispieldaten? Beispielcode?
-
Ausgehend von deinem letzten Thread hier mal eine Algo (SSE3: haddps, masm-syntax )zur Multiplikation von 4x4 Matrizen (singel). Die Matrizen müssen aligned 16 sein damit es klappt:
; matrix A,B und Dest müssen aligned 16 sein! ; (alternativ movdqa durch movdqu ersetzen) mul4x4 proc pmA:PVOID,pmB:PVOID,pmDest:PVOID mov eax,pmA mov edx,pmB mov ecx,pmDest movdqa xmm0,OWORD ptr [edx+0*16] ; lade matrix B movdqa xmm6,OWORD ptr [edx+1*16] ; movdqa xmm4,OWORD ptr [edx+2*16] ; movdqa xmm7,OWORD ptr [edx+3*16] ; movdqa xmm2,xmm0 movdqa xmm5,xmm4 unpcklps xmm0,xmm6 unpcklps xmm4,xmm7 unpckhps xmm2,xmm6 unpckhps xmm5,xmm7 movdqa xmm1,xmm0 movdqa xmm3,xmm2 unpcklpd xmm0,xmm4 ; = Spalte 1 unpckhpd xmm1,xmm4 ; = ... 2 unpcklpd xmm2,xmm5 ; = ... 3 unpckhpd xmm3,xmm5 ; = ... 4 ; A11-A14 movdqa xmm4,OWORD ptr [eax+0*16] movdqa xmm5,xmm4 movdqa xmm6,xmm4 movdqa xmm7,xmm4 mulps xmm4,xmm0 mulps xmm5,xmm1 mulps xmm6,xmm2 mulps xmm7,xmm3 haddps xmm4,xmm4 haddps xmm4,xmm4 haddps xmm5,xmm5 haddps xmm5,xmm5 haddps xmm6,xmm6 haddps xmm6,xmm6 haddps xmm7,xmm7 haddps xmm7,xmm7 unpcklps xmm4,xmm5 unpcklps xmm6,xmm7 unpcklpd xmm4,xmm6 movdqa OWORD ptr [ecx+0*16],xmm4 ; A21-A24 movdqa xmm4,OWORD ptr [eax+1*16] movdqa xmm5,xmm4 movdqa xmm6,xmm4 movdqa xmm7,xmm4 mulps xmm4,xmm0 mulps xmm5,xmm1 mulps xmm6,xmm2 mulps xmm7,xmm3 haddps xmm4,xmm4 haddps xmm4,xmm4 haddps xmm5,xmm5 haddps xmm5,xmm5 haddps xmm6,xmm6 haddps xmm6,xmm6 haddps xmm7,xmm7 haddps xmm7,xmm7 unpcklps xmm4,xmm5 unpcklps xmm6,xmm7 unpcklpd xmm4,xmm6 movdqa OWORD ptr [ecx+1*16],xmm4 ; A31-A34 movdqa xmm4,OWORD ptr [eax+2*16] movdqa xmm5,xmm4 movdqa xmm6,xmm4 movdqa xmm7,xmm4 mulps xmm4,xmm0 mulps xmm5,xmm1 mulps xmm6,xmm2 mulps xmm7,xmm3 haddps xmm4,xmm4 haddps xmm4,xmm4 haddps xmm5,xmm5 haddps xmm5,xmm5 haddps xmm6,xmm6 haddps xmm6,xmm6 haddps xmm7,xmm7 haddps xmm7,xmm7 unpcklps xmm4,xmm5 unpcklps xmm6,xmm7 unpcklpd xmm4,xmm6 movdqa OWORD ptr [ecx+2*16],xmm4 ; A41-A44 movdqa xmm4,OWORD ptr [eax+3*16] mulps xmm0,xmm4 mulps xmm1,xmm4 mulps xmm2,xmm4 mulps xmm3,xmm4 haddps xmm0,xmm0 haddps xmm0,xmm0 haddps xmm1,xmm1 haddps xmm1,xmm1 haddps xmm2,xmm2 haddps xmm2,xmm2 haddps xmm3,xmm3 haddps xmm3,xmm3 unpcklps xmm0,xmm1 unpcklps xmm2,xmm3 unpcklpd xmm0,xmm2 movdqa OWORD ptr [ecx+3*16],xmm0 ; ; A41-A44 ; movdqa xmm4,OWORD ptr [eax+3*16] ; movdqa xmm5,xmm4 ; movdqa xmm6,xmm4 ; movdqa xmm7,xmm4 ; mulps xmm4,xmm0 ; mulps xmm5,xmm1 ; mulps xmm6,xmm2 ; mulps xmm7,xmm3 ; haddps xmm4,xmm4 ; haddps xmm4,xmm4 ; haddps xmm5,xmm5 ; haddps xmm5,xmm5 ; haddps xmm6,xmm6 ; haddps xmm6,xmm6 ; haddps xmm7,xmm7 ; haddps xmm7,xmm7 ; unpcklps xmm4,xmm5 ; unpcklps xmm6,xmm7 ; unpcklpd xmm4,xmm6 ; movdqa OWORD ptr [ecx+3*16],xmm4 ret mul4x4 endp