SSE - Aktivierung notwendig? Mein SSE-Code ist 20x langsamer als Standard C



  • Hallo Zusammen,

    ich hoffe mir kann jemand helfen.
    Ich bin vor Kurzem intensiv in die SIMD-Programmierung eingestiegen. Ich verwende MS Visual Studio 6.0 und MS Visual Studio 2005 (beides getestet). Ich habe es sowohl mit den Compiler Intrinsics versucht, als auch mit dem Inline-Assembler. Zum testen der SSE-Funktionalitaet habe ich die Library "asmlib" verwendet, die unter http://www.agner.org/optimize/ zu finden ist. Prinzipiell ist also SSE-Unterstuetzung vorhanden.

    Meine Standard C++ Implementierung habe ich mit MS Visual Studio 6.0 ohne ProzessorPack (!) erzeugt. Diese "Standard-Implemetierung" hat also keinerlei SSE Befehle verwendet. Vor Kurzem habe ich nun eine SSE-Version erzeugt, die zu meiner Ueberraschung statt doppelt so schnell 20 mal langsamer war. Bisher konnte ich auch nach intensiver Web-Recherche dieses Problem nicht beheben. Ich habe es mittlerweile auch mit MS Visual Studio 2005 versucht - kein Erfolg soweit. Die Option /arch:SSE bewirkt auch nichts.

    Also, hier der relevante Code. Zuerst in der "Standard-Version"

    // pure C++-Code
    
    for (i=0;i<num;i++)
    {
    	// arithmetic operation
    	temp = (*a1)*(*sT)+(*a2)*(*sTT)+(*cb1)*vT+(*cb2)*vTT;
    
    	// save the result
    	(*sTT)  = temp;
    
    	// calculate sum
    	b += temp;
    
    	// increment the pointers
    	sT++;
    	sTT++;
    	a1++;
    	a2++;
    	cb1++;
    	cb2++;
    }
    

    Ziemlich straight-forward und ideal parallelisierbar.
    Hier mein Versuch mit dem Inline-Assembler:

    num4 = num/4;
    
    __asm {
    	// store variables
    	push			ebx
    	push			esi
    	push			edi
    
    	movss			xmm5,		vt1
    	movss			xmm7,		vt2
    	shufps			xmm5,		xmm5,		0x00
    	shufps			xmm7,		xmm7,		0x00
    
    	// load pointers
    	mov			eax,		stateT
    	mov			ebx,		stateTT
    	mov			ecx,		a1
    	mov			edx,		a2
    	mov			esi,		cb1
    	mov			edi,		cb2
    
    	// begin loop
    loop_begin:
    	// load data
    	movaps			xmm0,		[ecx]
    	movaps			xmm2,		[edx]
    	movaps			xmm4,		[esi]		
    	movaps			xmm6,		[edi]		
    	movaps			xmm1,		[eax]			
    	movaps			xmm3,		[ebx]		
    
    	// arithmetric operations
    	mulps			xmm0,		xmm1
    	add			eax,		16
    	mulps			xmm2,		xmm3
    	mulps			xmm4,		xmm5
    	add			ecx,		16
    	mulps			xmm6,		xmm7
    	add			edx,		16
    	addps			xmm0,		xmm2
    	add			esi,		16
    	addps			xmm4,		xmm6
    	add			edi,		16
    	addps			xmm0,		xmm4
    
    	// store result 
    	movaps			[ebx],			xmm0
    	add			ebx,			16
    	addps			xmm0,			[b4]
    	movaps			[b4],			xmm0
    
    	// increase pointers:  done in-between the arithmetic operations		
    
    	// next cycle
    	dec			num4
    	jnz			loop_begin
    
    	// restore variables 
    	pop			edi
    	pop			esi
    	pop			ebx
    }
    

    Der drastische Performance-Unterschied (Faktor 20 in die falsche Richtung) kann kein Zufall sein. Die Arrays sind alle auf 16 Byte "aligned", daran liegt es also auch nicht. Die Zahl der Iterationen ist num=1000, es kann also auch kaum an irgendeinem Funktionen-Oberhead liegen.

    Wahrscheinlich ist es ein ziemlich bloeder Fehler - wie so oft. Ich hoffe irgendjemand von euch hat Erfahrungen mit SSE-Programmierung. Muss man die SSE-Anweisungen erst irgendwie aktivieren? Kann es sein, dass SSE bei mir emuliert wird?

    Viele Gruesse,
    Stefan



  • Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum MFC (Visual C++) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


Anmelden zum Antworten