c++ x86 sse simd intrinsics

c++ - SIMD y diferencia entre doble precisión compacta y escalar



x86 sse (2)

Estoy leyendo la guía de intrínsecos de Intel al implementar el soporte SIMD. Tengo algunas confusiones y mis preguntas son las siguientes.

  1. __m128 _mm_cmpeq_ps (__m128 a, __m128 b) documentación dice que se usa para comparar puntos flotantes de precisión simple empaquetados. ¿Qué significa "empacado"? ¿Debo empaquetar mis valores flotantes de alguna manera antes de que pueda usarlos?

  2. Para la precisión doble existen intrínsecos como _mm_cmpeq_sd que significa que se comparan los elementos de punto flotante de doble precisión "inferior". ¿Qué significan los elementos dobles de precisión superior e inferior? ¿Puedo usarlos para comparar un vector de elementos de tipo double de C ++ o no? ¿O debo procesarlos de alguna manera antes de compararlos?


En SSE, los registros de 128 bits se pueden representar como 4 elementos de 32 bits.

SSE define dos tipos de operaciones; escalar y embalado. La operación escalar solo opera en el elemento de datos menos significativo (bit 0 ~ 31), y la operación empaquetada computa los cuatro elementos en paralelo.

_mm_cmpeq_sd solo compararía el elemento de datos menos significativo (primeros 32 bits) de los dos operandos, mientras que _mm_cmpeq_ps compararía cada grupo de 32 bits en paralelo.

Si usa 64 bits dobles, puede empacar el doble por pares para hacer uso del espacio de 128 bits. De esta forma, _mm_cmpeq_ps podría hacer dos comparaciones de 4 dobles en paralelo.

Si desea hacer solo una comparación a la vez, puede usar _mm_cmpeq_pd para comparar dos 64 bits dobles .

Tenga en cuenta que _mm_cmpeq_pd es SSE2, mientras que _mm_cmpeq_ps es SSE.


En este contexto, "empaquetado" significa "varios del mismo tipo colocados en un solo bloque", por lo que "punto flotante de precisión simple empaquetado" significa números de coma flotante de 4 * 32 bits almacenados como un valor de 128 bits.

O bien debe "empaquetar" cada valor en el registro usando varias instrucciones PACK* , o tener los datos ya "empaquetados" en la memoria, por ejemplo, una matriz de (múltiplos de) 4 valores de coma flotante [que están adecuadamente alineados].

Escalar significa "un valor" en los n bits más bajos del registro (por ejemplo, un double serían los 64 bits bajos de un registro SSE de 128 bits).