Estoy tratando de normalizar un vector 4d.¿Normalización de SSE más lenta que la aproximación simple?
Mi primera aproximación fue utilizar intrínsecamente SSE, algo que proporcionó un impulso de velocidad 2 veces a mi aritmética vectorial. Aquí es el código básico: (v.v4 es la entrada) (usando GCC) (todo esto se colocarán en línea)
//find squares
v4sf s = __builtin_ia32_mulps(v.v4, v.v4);
//set t to square
v4sf t = s;
//add the 4 squares together
s = __builtin_ia32_shufps(s, s, 0x1B);
t = __builtin_ia32_addps(t, s);
s = __builtin_ia32_shufps(s, s, 0x4e);
t = __builtin_ia32_addps(t, s);
s = __builtin_ia32_shufps(s, s, 0x1B);
t = __builtin_ia32_addps(t, s);
//find 1/sqrt of t
t = __builtin_ia32_rsqrtps(t);
//multiply to get normal
return Vec4(__builtin_ia32_mulps(v.v4, t));
puedo comprobar el desmontaje y parece que la forma en que se puede esperar. No veo ningún gran problema allí.
De todas formas, a continuación, lo probé usando una aproximación: (Tengo esto desde Google)
float x = (v.w*v.w) + (v.x*v.x) + (v.y*v.y) + (v.z*v.z);
float xhalf = 0.5f*x;
int i = *(int*)&x; // get bits for floating value
i = 0x5f3759df - (i>>1); // give initial guess y0
x = *(float*)&i; // convert bits back to float
x *= 1.5f - xhalf*x*x; // newton step, repeating this step
// increases accuracy
//x *= 1.5f - xhalf*x*x;
return Vec4(v.w*x, v.x*x, v.y*x, v.z*x);
Se está ejecutando un poco más rápido que la versión SSE! (aproximadamente 5-10% más rápido) Sus resultados también son muy precisos, ¡diría que a 0.001 cuando encuentre longitud! Pero ... GCC me está dando esa regla de alias estricta y coja debido al tipo de juego de palabras.
Así que modifica:
union {
float fa;
int ia;
};
fa = (v.w*v.w) + (v.x*v.x) + (v.y*v.y) + (v.z*v.z);
float faHalf = 0.5f*fa;
ia = 0x5f3759df - (ia>>1);
fa *= 1.5f - faHalf*fa*fa;
//fa *= 1.5f - faHalf*fa*fa;
return Vec4(v.w*fa, v.x*fa, v.y*fa, v.z*fa);
Y ahora la versión modificada (sin advertencias) va más lento de !! ¡Corre casi el 60% de la velocidad que ejecuta la versión SSE (pero el mismo resultado)! ¿Por qué es esto?
Así que aquí es la pregunta (s):
- ¿Es mi implementació SSE correcta?
- ¿El SSE es realmente más lento que las operaciones de fpu normales?
- ¿Por qué demonios es el 3er código mucho más lento?
Ayudaría saber qué CPU está utilizando. P.ej. antiguas CPUs x86 (pre Core 2) tenían capacidades SSE muy pobres. –
Estoy en un Intel Pentium Dual-Core – Pubby
Duplicado de http://stackoverflow.com/questions/1528727/why-is-sse-scalar-sqrtx-slower-than-rsqrtx-x? – celion