如何使用 SSE 指令取浮点数的倒数(逆),但是仅适用于非零 values?
背景如下:
我想规范化向量数组,以便每个维度具有相同的平均值。在 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 本质来完成此操作。 Setp 1 和步骤 3 很简单,但我被困在步骤 2 上。我似乎没有找到任何代码示例或明显的 SSE 指令来取值的倒数if它不为零。
对于除法,_mm_rcp_ps 可以解决这个问题,并且可能将其与条件移动结合起来,但是如何获得指示哪个分量为零的掩码?
我不需要上述算法的代码,只需要“如果不为零则逆”函数:
__m128 rcp_nz_ps(__m128 input) {
// ????
}
Thanks!
__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
设置为b111...11
如果输入为零,并且b000...00
否则。 And-not 使用该掩码将与零输入相对应的倒数元素替换为零。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)