2010-04-11 9 views
10

Esto está específicamente relacionado con la codificación ARM Neon SIMD. Estoy usando ARM Neon instrinsics para cierto módulo en un decodificador de video. Tengo un vectorizado de datos de la siguiente manera:¿Cómo reordeno los datos vectoriales utilizando los intrínsecos de ARM Neon?

Hay cuatro elementos de 32 bits en un registro de Neon, digamos, Q0, que es del tamaño de 128 bits.

3B 3A 1B 1A 

Hay otros cuatro elementos de 32 bits en otro registro de Neon, digamos Q1 que es de tamaño 128 bit.

3D 3C 1D 1C 

Quiero que los datos finales a estar en orden, como se muestra a continuación:

1D 1C 1B 1A 
3D 3C 3B 3A 

Lo instrinsics neón puede lograr el fin deseado de datos?

+0

Typo en el último pedido de datos? ¿Debería ser '3D 3C 3B 3A'? –

+0

@Paul R: Gracias, lo corrigió. – goldenmean

Respuesta

9

¿qué tal algo como esto:

int32x4_t q0, q1; 

    /* split into 64 bit vectors */ 
    int32x2_t q0_hi = vget_high_s32 (q0); 
    int32x2_t q1_hi = vget_high_s32 (q1); 
    int32x2_t q0_lo = vget_low_s32 (q0); 
    int32x2_t q1_lo = vget_low_s32 (q1); 

    /* recombine into 128 bit vectors */ 
    q0 = vcombine_s32 (q0_lo, q1_lo); 
    q1 = vcombine_s32 (q0_hi, q1_hi); 

En teoría, esto debería compilar a sólo dos instrucciones de movimiento debido a que el vget_high y vget_low simplemente reinterpretan los registros Q 128 bits como dos registros de 64 bits D. vcombine otoh simplemente compila a uno o dos movimientos (depende de la asignación del registro).

Ah, y el orden de los enteros en la salida podría ser exactamente el camino equivocado. De ser así, simplemente cambie los argumentos a vcombine_s32.

3

Parece que debería poder usar la instrucción VTRN (por ejemplo, vtrnq_u32) para esto.

+0

@Paul: vtrnq_u32 no ayuda. De hecho, necesito hacer algo como VTRN.64, pero lamentablemente no hay instrucciones/intrínsecas como VTRN.64. – goldenmean

+0

@goldenmean: lo siento, ya veo lo que quiere decir ahora. Parece que NEON no cuenta con operaciones permute/shuffle de propósito general. –

+0

El enlace está caído ... – Antonio

4

Recuerde que cada registro q se compone de dos registros d, por ejemplo, la parte baja de q0 es d0 y la parte alta d1. De hecho, esta operación simplemente está cambiando d0 y d3 (o d1 y d2, no está del todo claro desde la presentación de datos). ¡Incluso hay una instrucción de intercambio para hacerlo en una instrucción!

Descargo de responsabilidad: No conozco los intrínsecos de Neon (código directamente en el ensamblaje), aunque me sorprendería si esto no se pudiera hacer usando intrínsecos.

2

Pierre tiene razón.

d0 VSWP, d3

que va a hacer.

@Pierre: Leí la publicación sobre NEON en su blog hace varios meses. Me sorprendió gratamente que hubiera alguien como yo, escribiendo códigos de ensamblaje optimizados a mano, tanto ARM como NEON. Encantado de verte.

Cuestiones relacionadas