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.


  • Mod

    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
    

Anmelden zum Antworten