2011-08-03 15 views
6

Soy bastante nuevo para ensamblar y aunque el centro de información de brazo a menudo es útil, a veces las instrucciones pueden ser un poco confusas para un novato. Básicamente, lo que tengo que hacer es sumar 4 valores de flotación en un registro de cuatro palabras y almacenar el resultado en un solo registro de precisión. Creo que la instrucción VPADD puede hacer lo que necesito, pero no estoy muy seguro.Suma todos los elementos en un vector de cuatro palabras en el ensamblaje ARM con NEON

Respuesta

2

Parece que desea obtener la suma de una determinada longitud de matriz, y no solo cuatro valores de flotación.

En ese caso, su código funcionará, pero está lejos de ser optimizados:

  1. muchos muchos bloqueos de tuberías

  2. además de 32 bits innecesarios por iteración

suponiendo que la longitud de la matriz es un múltiplo de 8 y al menos 16:

vldmia {q0-q1}, [pSrc]! 
    sub count, count, #8 
loop: 
    pld [pSrc, #32] 
    vldmia {q3-q4}, [pSrc]! 
    subs count, count, #8 
    vadd.f32 q0, q0, q3 
    vadd.f32 q1, q1, q4 
    bgt loop 

    vadd.f32 q0, q0, q1 
    vpadd.f32 d0, d0, d1 
    vadd.f32 s0, s0, s1 
  • pld, aunque es una instrucción ARM y no NEON, es crucial para el rendimiento. Aumenta drásticamente la tasa de aciertos de la memoria caché.

Espero que el resto del código anterior se explique por sí mismo.

Notarás que esta versión es mucho más rápida que la inicial.

2

puede probar con esto (que no está en ASM, pero debe ser capaz de convertir fácilmente):

float32x2_t r = vadd_f32(vget_high_f32(m_type), vget_low_f32(m_type)); 
return vget_lane_f32(vpadd_f32(r, r), 0); 

En ASM sería probablemente sólo VADD y VPADD.

no estoy seguro si esto es sólo un método para hacer esto (y más óptimo), pero no se han dado cuenta/encontrado uno mejor ...

PS. Soy nuevo al neón demasiado

+0

Gracias logré que esto funcionara usando un VPADD y dos VADD. Esperaba tener que usar solo 1 o 2 instrucciones, pero creo que 3 solo tendrá que hacer. –

+0

¿Podría mostrar su ASM? Creo que requerirá solo un VADD y un VPADD (al menos que se ve desde el código C) – kibab

2

Aquí está el código en ASM:

vpadd.f32 d1,d6,d7 @ q3 is register that needs all of its contents summed   
    vadd.f32 s1,s2,s3  @ now we add the contents of d1 together (the sum)     
    vadd.f32 s0,s0,s1  @ sum += s1; 

puedo haber olvidado mencionar que en el código C se vería así:

float sum = 1.0f; 
sum += number1 * number2; 

tengo omitió la multiplicación de esta pequeña pieza como código.

Cuestiones relacionadas