2012-04-16 8 views
10

C'è un modo per controllare se tutti i bit/byte/parole ecc. In una variabile __m128i sono 0?
Nella mia app devo verificare se tutti gli interi contenuti in una variabile __m128i sono zero. Dovrò estrarli e confrontarli separatamente?

Edit: Controllare il registro XMM per tutti gli zeri


Quello che sto facendo ora è:

int next = 0; 
do{ 
    //some code 

    next = idata.m128i_i32[0] + idata.m128i_i32[1] + idata.m128i_i32[2] + idata.m128i_i32[3]; 
}while(next > 0); 

Che cosa ho bisogno è quello di verificare se idata è tutti zero, senza dover accedere ogni singolo elemento, e chiudere il ciclo se sono ...

Basato sul commento di Harold questa è la soluzione:


__m128i idata = _mm_setr_epi32(i,j,k,l); 
do{ 
    //some code 
}while(!_mm_testz_si128(idata, idata)); 

Questo uscirà dal ciclo se tutti i bit bassi di ciascun DW in idata sono 0 ... grazie hraold!

+0

Non è possibile utilizzare, ad esempio, 'PCMPEQD' per confrontare senza estrazione? – dasblinkenlight

+0

I registri XMM hanno un registro flag ad essi allegato? Se sì, ci deve essere un flag di zero tra questi bit. –

+3

Vedere 'PTEST' è SSE4 disponibile, altrimenti richiede uno sforzo leggermente maggiore. – harold

risposta

9

_mm_testz_si128 è SSE4.1 che non è supportato su alcune CPU (ad esempio Intel Atom, AMD Phenom)

Ecco uno SSE2 compatibile variante

inline bool isAllZeros(__m128i xmm) { 
    return _mm_movemask_epi8(_mm_cmpeq_epi8(xmm, _mm_setzero_si128())) == 0xFFFF; 
} 
4

Come Paolo R commentato alla mia originale post:

"Non è necessario inizializzare un argomento fittizio per il secondo parametro di PTEST, ovvero invece di _mm_testz_si128(idata, _mm_set1_epi32(0xFFFF)) è sufficiente testare un valore contro se stesso."

ptest esegue l'intero processo con un'unica istruzione.

Questo ha aiutato.

Problemi correlati