SSE: wechselseitig, wenn nicht null

Wie kann ich den Kehrwert von Floats mit SSE-Anweisungen nehmen, abernur für nicht null Werte?

Hintergrund unten:

Ich möchte ein Array von Vektoren normalisieren, damit jede Dimension den gleichen Durchschnitt hat. In C kann dies wie folgt codiert werden:

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];

Aus Gründen der Leistung möchte ich dies jetzt mit SSE-Intinsics tun. Schritt 1 und Schritt 3 sind einfach, aber ich bleibe bei Schritt 2. Ich finde offenbar kein Codebeispiel oder keine offensichtliche SSE-Anweisung, um den Kehrwert eines Werts zu ermittelnob es ist nicht null. Für die Division macht _mm_rcp_ps den Trick und kombiniert ihn möglicherweise mit einer bedingten Bewegung, aber wie erhält man eine Maske, die angibt, welche Komponente Null ist?

Ich brauche den Code für den oben beschriebenen Algorithmus nicht, nur die Funktion "invers wenn nicht Null":

__m128 rcp_nz_ps(__m128 input) {
    // ????
}

Vielen Dank!

Antworten auf die Frage(1)

Ihre Antwort auf die Frage