2012-04-25 28 views
6

Donde las instrucciones SSE del x86-64 (instrucciones vectoriales) superan las instrucciones normales. Porque lo que estoy viendo es que las cargas y las tiendas frecuentes que se requieren para ejecutar las instrucciones de SSE anulan cualquier ganancia que tenemos debido al cálculo del vector. Entonces, ¿podría alguien darme un código SSE de ejemplo en el que funcione mejor que el código normal?Donde las instrucciones SSE superan las instrucciones normales

Su tal vez porque estoy pasando cada parámetro por separado, así ...

__m128i a = _mm_set_epi32(pa[0], pa[1], pa[2], pa[3]); 
__m128i b = _mm_set_epi32(pb[0], pb[1], pb[2], pb[3]); 
__m128i res = _mm_add_epi32(a, b); 

for(i = 0; i < 4; i++) 
po[i] = res.m128i_i32[i]; 

no está allí una manera que puedo pasar todos los 4 números enteros en una sola vez, me refiero a pasar todo el 128 bytes de pa de una sola vez? ¿Y asignar res.m128i_i32 al po de una vez?

+1

Básicamente, cada vez que tenga una muy alta computación/load-store proporción. – Mysticial

+2

Sí, definitivamente no quiere usar '_mm_set_epi32()' así. Use '_mm_load_si128()'.Y si no puede alinear los datos, puede usar '_mm_loadu_si128()' con una penalización de rendimiento. – Mysticial

+1

¿Alinea los datos? ¿Que quieres decir con eso? – pythonic

Respuesta

10

resumen de los comentarios en una respuesta:

Se han básicamente caído en la misma trampa que atrapa la mayoría de los novatos. Básicamente hay dos problemas en su ejemplo:

  1. Está haciendo un uso indebido _mm_set_epi32().
  2. Tiene una relación de cómputo/carga-tienda muy baja. (1 a 3 en su ejemplo)

_mm_set_epi32() es un muy caro intrínseca. Aunque es conveniente de usar, no se compila en una sola instrucción. Algunos compiladores (como VS2010) pueden generar un código de rendimiento muy pobre al usar _mm_set_epi32().

En su lugar, como está cargando bloques de memoria contiguos, debe usar _mm_load_si128(). Eso requiere que el puntero esté alineado a 16 bytes. Si no puede garantizar esta alineación, puede usar _mm_loadu_si128(), pero con una penalización de rendimiento. Idealmente, debe alinear correctamente sus datos para que no tenga que recurrir al uso de _mm_loadu_si128().


Para ser realmente eficiente con SSE, también querrá maximizar su relación de cómputo/carga-almacén. Un objetivo para el que disparo es de 3 a 4 instrucciones aritméticas por acceso a la memoria. Esta es una relación bastante alta. Normalmente, debe refactorizar el código o rediseñar el algoritmo para aumentarlo. La combinación de pases sobre los datos es un enfoque común.

El desenrollado de bucles a menudo es necesario para maximizar el rendimiento cuando tiene cuerpos de bucles grandes con largas cadenas de dependencia.


Algunos ejemplos de preguntas de SO que utilizan SSE con éxito para lograr una aceleración.

Cuestiones relacionadas