2012-02-06 6 views
11

Voglio convertire un array di numeri brevi senza segno in float usando SSE. DiciamoSSE: converti numero intero short in float

__m128i xVal;  // Has 8 16-bit unsigned integers 
__m128 y1, y2; // 2 xmm registers for 8 float values 

voglio prima 4 uint16 in Y1 & prossimo 4 uint16 in y2. Bisogno di sapere quale sse intrinseca usare.

risposta

17

È necessario scompattare il tuo primo vettore di 8 x 16 bit pantaloncini firmati in due vettori di 32 bit unsigned int, poi convertire ognuno di questi vettori a float:

__m128i xlo = _mm_unpacklo_epi16(x, _mm_set1_epi16(0)); 
__m128i xhi = _mm_unpackhi_epi16(x, _mm_set1_epi16(0)); 
__m128 ylo = _mm_cvtepi32_ps(xlo); 
__m128 yhi = _mm_cvtepi32_ps(xhi); 
+0

grazie .. questo funziona – krishnaraj

+0

questo è quello che farei anch'io con l'eccezione che io ' d usa uno _mm_setzero_si128(), invece di due _mm_set1_epi16. – Magnus

+0

@Magnus: Penso che troverete che il codice generato è lo stesso in entrambi i casi, almeno con i compilatori più decenti. –

6

Vorrei suggerire di usare un po ' versione diversa:

static const __m128i magicInt = _mm_set1_epi16(0x4B00); 
static const __m128 magicFloat = _mm_set1_ps(8388608.0f); 

__m128i xlo = _mm_unpacklo_epi16(x, magicInt); 
__m128i xhi = _mm_unpackhi_epi16(x, magicInt); 
__m128 ylo = _mm_sub_ps(_mm_castsi128_ps(xlo), magicFloat); 
__m128 yhi = _mm_sub_ps(_mm_castsi128_ps(xhi), magicFloat); 

Sul livello di assieme l'unica differenza dalla versione Paul R è l'utilizzo di _mm_sub_ps (istruzione SUBPS) anziché _mm_cvtepi32_ps (istruzione CVTDQ2PS). _mm_sub_ps non è mai più lento di _mm_cvtepi32_ps, ed è effettivamente più veloce su vecchie CPU e su CPU a bassa potenza (leggi: Intel Atom e AMD Bobcat)

+1

Non sono del tutto convinto che sia comunque meglio. Prendi un colpo di latenza di 1-2 cicli per spostare i dati da SSE-int a SSE-FP. Quindi sono necessari due registri aggiuntivi (o carichi) per le due costanti. Questo trucco è più comunemente usato per la precisione doppia. – Mysticial

+1

CVTDQ2PS soffre anche di penalità di transizione da SSE-INT a SSE-FP. L'aumento della pressione di registro potrebbe essere un problema, ma dipende in gran parte dal codice circostante. –

+0

Giusto, ho trascurato quello. :) +1 – Mysticial