2012-04-16 13 views
10

¿Hay alguna forma de comprobar si todos los bits/bytes/palabras, etc. en una variable __m128i son 0?
En mi aplicación, tengo que verificar si todos los enteros empaquetados en a en una variable __m128i son ceros. ¿Tendré que extraerlos y compararlos por separado?

Editar: Comprobar el registro XMM para todos los ceros


Lo que estoy haciendo ahora es:

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); 

Lo que necesito es para comprobar si idata es todo ceros sin tener que acceder a cada elemento individual, y salga del bucle si están ...

Basado en el comentario de Harold esta es la solución:


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

Esto saldrá del bucle si todos los bits bajos de cada DW en idata son 0 ... gracias Hraold!

+0

¿No puedes usar, por ejemplo, 'PCMPEQD' para comparar sin extracción? – dasblinkenlight

+0

¿Los registros XMM tienen un registro de bandera adjunto? En caso afirmativo, debe haber un indicador de cero entre estos bits. –

+3

Ver 'PTEST 'es SSE4 disponible, de lo contrario, requerirá un poco más de esfuerzo. – harold

Respuesta

9

_mm_testz_si128 es SSE4.1 que no está soportado en algunas CPU (por ejemplo, Intel Atom, AMD Phenom)

Aquí es una variante compatible con SSE2-

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

Como Pablo R comentó a mi original publicación:

"No necesita inicializar un argumento ficticio para el segundo parámetro de PTEST, es decir, en lugar de _mm_testz_si128(idata, _mm_set1_epi32(0xFFFF)) puede probar un valor contra sí mismo".

ptest hace todo el trabajo con una sola instrucción.

Esto ayudó.

Cuestiones relacionadas