2010-12-19 15 views
11

Supongamos que tengo una matriz:indexación en una matriz con SSE

uint8_t arr[256]; 

y un elemento

__m128i x 

que contiene 16 bytes,

x_1, x_2, ... x_16 

me gustaría llenar eficientemente una nuevo __m128i elemento

__m128i y 

con valores de arr función de los valores en x, tal que:

y_1 = arr[x_1] 
y_2 = arr[x_2] 
    . 
    . 
    . 
y_16 = arr[x_16] 

Un comando para lograr esto estaría esencialmente cargando un registro de un conjunto no contiguo de ubicaciones de memoria. Tengo un recuerdo dolorosamente vago de haber visto la documentación de tal comando, pero no puedo encontrarlo ahora. ¿Existe? Gracias de antemano por tu ayuda.

+0

Se arregló el formato del código; en el futuro, tenga en cuenta que si desea formatear un bloque de texto como código, debe sangrarlo con 4 espacios y dejar una línea en blanco (o simplemente seleccionarlo y presionar el botón '0101'). –

+1

@Matteo: Ya no es '101010'. Cambió a '{}' ... – thkala

+0

@thkala: eh, no me di cuenta, en general solo hago CTRL-K o copiar y pegar desde mi editor donde puedo agregar los 4 espacios presionando TAB (y puedo beneficio del resaltado de sintaxis). –

Respuesta

6

Este tipo de capacidad en las arquitecturas SIMD se conoce como load/store scatter/gather. Lamentablemente, SSE no lo tiene. Las futuras arquitecturas SIMD de Intel pueden tener esto: el malogrado procesador Larrabee fue uno de los ejemplos. Por ahora, solo necesitará diseñar sus estructuras de datos de tal manera que este tipo de funcionalidad no sea necesaria.

Tenga en cuenta que puede lograr el efecto equivalente al usar, p. _mm_set_epi8:

y = _mm_set_epi8(arr[x_16], arr[x_15], arr[x_14], ..., arr[x_1]); 

aunque por supuesto esto sólo generará un montón de código escalar para cargar el vector y. Esto está bien si está realizando este tipo de operación fuera de cualquier bucle de rendimiento crítico, p. como parte de la inicialización antes del bucle, pero dentro de un bucle es probable que sea un asesino de rendimiento.

+0

Gracias por la respuesta. "Gather/Scatter" es claramente el término que estaba buscando. Después de una breve inspección, parece que dicha funcionalidad está disponible en las GPU. ¿Algún consejo a lo largo de esas líneas? – Travis

+0

Incluso en GPU esto puede ser ineficiente, ya que cargar/almacenar en/desde diferentes direcciones de memoria inevitablemente significará más ciclos de bus. –