1

因此,我使用 SSE2 编写了一个函数,该函数对向量进行了限制,但它似乎只适用于某些目的,例如它适用于我的双线性过滤算法,但当用于执行模运算时,它会产生略微偏离的值。该函数通过使用截断执行转换为整数向量并将其转换回浮点来工作。下面列出了底数和模数代码:

inline __m128 floor_SIMD(const __m128 & a)
{
    __m128i int_val = _mm_cvttps_epi32(a);
    return _mm_cvtepi32_ps(int_val); 
}

inline __m128 mod_SIMD(const __m128 & x, const __m128 & y)
{
    return _mm_sub_ps(x, _mm_mul_ps(y, floor_SIMD(_mm_div_ps(x, y))));
}

可能有人能解释为什么我的模数有点奇怪吗?

编辑:例如,当使用 mod_SIMD(_mm_set1_ps(63.6f), _mm_set1_ps(32.0f)) 时会产生错误的答案,但 mod_SIMD(_mm_set1_ps(23.6f), _mm_set1_ps(32.0f)) 会产生正确的答案。当我用效率低得多的组件明智版本替换 floor 功能时,它可以正常工作。

4

1 回答 1

3

我解决了我自己的问题。为了大家的利益,这里是我生成的代码。如果它大于补偿截断问题的原始值,它会从值中减去一个

inline __m128 floor_SIMD(const __m128 & a)
{
    static const __m128 one = _mm_set1_ps(1.0f);

    __m128 fval = _mm_cvtepi32_ps(_mm_cvttps_epi32(a));

    return _mm_sub_ps(fval, _mm_and_ps(_mm_cmplt_ps(a, fval), one));
}
于 2013-05-10T18:48:10.167 回答