2012-05-14 18 views
10

Ho una grande funzione di elaborazione dei pixel che attualmente sto tentando di ottimizzare utilizzando le funzioni intrinseche.Tabella di ricerca utilizzando SIMD

Essendo un novizio SSE, non sono sicuro di come affrontare la parte del codice che coinvolge le tabelle di ricerca.

In sostanza, sto cercando di vettorizzare il seguente codice alla vaniglia C++:

//outside loop 
const float LUT_RATIO = 1000.0F; 

//in loop 
float v = ... //input value 
v = myLookupTable[static_cast<int>(v * LUT_RATIO)]; 

Quello che sto cercando:

//outside loop 
const __m128 LUT_RATIO = _mm_set1_ps(1000.0F); 

//in loop 
__m128 v = _mm_set_ps(v1, v2, v3, v4); //input values 
__m128i vI = _mm_cvtps_epi32(_mm_mul_ps(v, LUT_RATIO)); //multiply and convert to integers 
v = ??? // how to get vI indices of myLookupTable? 

edit: Ildjarn fa un punto che richiede un chiarimento da parte mia. Non sto cercando di ottenere l'accelerazione per il codice della tabella di ricerca, sto semplicemente cercando di evitare di archiviare i registri su float appositamente per fare la ricerca, poiché questa parte è inserita tra 2 altre parti che potrebbero teoricamente beneficiare di SSE.

+0

Chi ti ha convinto che puoi migliorare su 'myLookupTable [static_cast (v) * LUT_RATIO]'? Non viene eseguito alcun calcolo qui, perché l'SSE potrebbe essere applicabile? – ildjarn

+2

@ildjarn Sono abbastanza sicuro di non poter migliorare questa parte in quanto tale, ma spero di migliorare altre parti della funzione e di evitare la penalità di spostarsi avanti e indietro tra '__m128' e' float [4] ' Devo anche vettorializzare questo codice. – Rotem

risposta

12

Se è possibile attendere fino al prossimo anno, le CPU Haswell di Intel disporranno di AVX2 che include istruzioni per i carichi raccolti. Questo ti permette di fare ad es. 8 ricerche LUT parallele in un'unica istruzione (vedere ad esempio VGATHERDPS). A parte questo, sei sfortunato, a meno che le tue LUT siano piuttosto piccole (ad esempio 16 elementi), nel qual caso puoi usare PSHUFB.

+0

Sfortunatamente le mie LUTs sono grandi 10000 elementi. Anche se dovessi aspettare un nuovo processore, ci vorranno anni prima che sia legittimo specificare Haswell come CPU minima. :) Grazie per le informazioni. – Rotem

+1

OK: se è possibile approssimare le LUT, ad es. con un polinomio, potresti ancora ottenere una vittoria con SSE, altrimenti temo che tu sia bloccato con il codice scalare. –

+3

Il codice scalare è quindi. Questa è una buona notizia in un certo senso, posso smettere di preoccuparmi di questa parte e andare a lavorare su parti che potrebbero rivelarsi più ottimizzabili. – Rotem