8

SSE 命令でfloatの逆数 (逆数) を取得するにはどうすればよいですか?

以下の背景:

各次元の平均が同じになるように、ベクトルの配列を正規化したいと考えています。C では、これは次のようにコーディングできます。

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

パフォーマンス上の理由から、SSE intinsics を使用してこれを行いたいと考えています。Setp 1 とステップ 3 は簡単ですが、ステップ 2 で行き詰まっています。値がゼロでない場合に値の逆数を取るためのコード サンプルや明白な SSE 命令が見つからないようです。除算では、_mm_rcp_ps がうまく機能し、条件付き移動と組み合わせることができますが、どのコンポーネントがゼロであるかを示すマスクを取得するにはどうすればよいでしょうか?

上記のアルゴリズムのコードは必要ありません。「ゼロでない場合は逆」関数だけです。

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

ありがとう!

4

1 に答える 1

13
__m128 rcp_nz_ps(__m128 input) {
    __m128 mask = _mm_cmpeq_ps(_mm_set1_ps(0.0), input);
    __m128 recip = _mm_rcp_ps(input);
    return _mm_andnot_ps(mask, recip);
}

の各レーンは、入力がゼロの場合にmask設定され、そうでない場合に設定されます。And-not with that mask は、ゼロ入力に対応する逆数の要素をゼロに置き換えます。b111...11b000...00

于 2012-05-15T18:18:37.043 に答える