¿Cómo puedo tomar el recíproco (inverso) de flotadores con instrucciones SSE, pero solo para valores distintos de cero?SSE: recíproco si no es cero
Antecedentes abajo:
Quiero normalizar un conjunto de vectores de manera que cada dimensión tiene la misma media. En C esto puede ser codificada como:
float vectors[num * dim]; // input data
// step 1. compute the sum on each dimension
float norm[dim];
memset(norm, 0, dim * sizeof(float));
for(int i = 0; i < num; i++) for(int j = 0; j < dims; j++)
norm[j] += vectors[i * dims + j];
// step 2. convert sums to reciprocal of average
for(int j = 0; j < dims; j++) if(norm[j]) norm[j] = float(num)/norm[j];
// step 3. normalize the data
for(int i = 0; i < num; i++) for(int j = 0; j < dims; j++)
vectors[i * dims + j] *= norm[j];
ahora por razones de rendimiento, yo quiero hacer esto utilizando intinsics SSE. Setp 1 et paso 3 son fáciles, pero estoy atascado en el paso 2. No parece encontrar ningún ejemplo de código o instrucción SSE obvia para tomar la recirculación de un valor si no es cero. Para la división, _mm_rcp_ps hace el truco, y tal vez combinarlo con un movimiento condicional, pero ¿cómo obtener una máscara que indique qué componente es cero?
No necesito el código para el algoritmo descrito anteriormente, sólo la "inversa si no es cero" función:
__m128 rcp_nz_ps(__m128 input) {
// ????
}
Gracias!
Maldición, eso fue rápido. Estaba trabajando solo y tú me ganaste. +1 – Mysticial
Gracias. ¿Hay alguna forma de "probar" en lugar de "comparar" y evitar el uso de un conjunto de registros como nulo? Sólo me preguntaba ... – Antoine
Además, en la última línea, hay un error tipográfico: la entrada debe ser recip. – Antoine