Intel, unglaublich schnell unglaublich ungenau



  • Hi!

    Ich spiele gerade mit SSE herum und habe 2 Funktionen zum Normalisieren eines
    Vektors geschrieben:

    normalize_vector_sse push ebp
    	mov ebp, esp
    
    	mov	eax,	dword[ebp+8]		; in
    	mov	ecx,	dword[ebp+12]		; out
    
    	movaps _sa,	[eax]
    	movaps first, [eax]
    
    	mulps	_sa,	_sa				; quadrieren
    	movaps _sb,	_sa
    	movaps _sc,	_sa
    
    	shufps	_sb, _sb, 0x55		; einzel quadrate isolieren
    	shufps	_sc, _sc, 0xAA
    	addss	_sa, _sb				; addieren
    	addss	_sa, _sc
    	sqrtss	_sa, _sa			; wurzel
    	shufps	_sa, _sa, 0x00		; länge isolieren
    	divps		first, _sa			; ur-vektor / länge
    
    	movaps [ecx], first
    
    	pop ebp
    ret
    
    normalize_vector_sse_fast push ebp
    	mov ebp, esp
    
    	mov	eax,	dword[ebp+8]		; in
    	mov	ecx,	dword[ebp+12]		; out
    
    	movaps _sa,	[eax]
    	movaps first, [eax]
    
    	mulps	_sa,	_sa				; quadrieren
    	movaps _sb,	_sa
    	movaps _sc,	_sa
    
    	shufps	_sb, _sb, 0x55		; einzel quadrate isolieren
    	shufps	_sc, _sc, 0xAA
    	addss	_sa, _sb				; addieren
    	addss	_sa, _sc
    	rsqrtss	_sa, _sa			; 1/wurzel
    	shufps	_sa, _sa, 0x00		; länge isolieren
    	mulps		first, _sa			; ur-vektor * 1/länge
    
    	movaps [ecx], first
    
    	pop ebp
    ret
    

    Die _fast Funktion nutzt eine schnellere rsqrtss, mulps-Kombi statt sqrtss und divps. Der Performanceunterschied ist auf meinem System gewaltig, _fast ist fast (versteckter Reim :)) doppelt so schnell 😮, leider aber auch wesentlich ungenauer.
    Mache ich was falsch? Wenn mir z.b. normalize_vector_sse als erste Koordinate 0.70710677 liefert, spuckt normalize_vector_sse_fast mit dem selben Input-Vektor 0.7069397 aus. Das ist imho außerhalb des Toleranzbereichs, besonders weil sich der Fehler mit der Zeit aufschaukeln kann.



  • Wundert dich das etwa? Es steht ja in der Dokumentation dieser Funktion, dass sie ungenau ist, aber dafür halt schnell.


Anmelden zum Antworten