Wie kann ich die reziproke (inverse) von Floats mit SSE-Anweisungen, aber nur für nicht Null Werte nehmen?SSE: reziprok wenn nicht null
Hintergrund unten:
Ich möchte ein Array von Vektoren normalisieren, so daß jede Dimension die gleiche durchschnittliche aufweist. In C kann diese codiert werden als:
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];
nun aus Leistungsgründen, ich möchte, dies zu tun SSE intinsics verwenden. Setp 1 und Step 3 sind einfach, aber ich stecke bei Schritt 2 fest. Ich finde anscheinend keine Code-Probe oder offensichtlichen SSE-Befehl, um das Rezirkular eines Wertes zu nehmen, wenn nicht Null ist. Für die Division macht _mm_rcp_ps den Trick und kombiniert es vielleicht mit einer bedingten Bewegung, aber wie erhält man eine Maske, die anzeigt, welche Komponente Null ist?
Ich brauche den Code nicht zu dem oben beschriebenen Algorithmus, sondern nur die „inverse wenn nicht Null“ Funktion:
__m128 rcp_nz_ps(__m128 input) {
// ????
}
Dank! sonst
Verdammt, das war schnell. Ich habe alleine gearbeitet und du hast mich dazu geschlagen. +1 – Mysticial
Danke. Gibt es eine Möglichkeit, "zu testen" anstatt "zu vergleichen", und zu vermeiden, einen Registersatz auf Null zu setzen? Ich frage mich nur ... – Antoine
Neben der letzten Zeile gibt es einen Tippfehler: Eingabe sollte recip sein. – Antoine