C++ 我的SSE2地板功能有一些问题

C++ 我的SSE2地板功能有一些问题,c++,optimization,sse,C++,Optimization,Sse,所以我用SSE2编写了一个函数,它可以对向量进行分层,但它似乎只适用于某些目的,例如,它对我的双线性滤波算法很好,但当用于执行模运算时,它会得到稍微偏离的值。该函数通过使用截断执行到整数向量的转换,并将其转换回浮点。地板和模数代码如下所示: inline __m128 floor_SIMD(const __m128 & a) { __m128i int_val = _mm_cvttps_epi32(a); return _mm_cvtepi32_ps(int_val);

所以我用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))将生成正确答案。当我用效率低得多的组件版本替换地板功能时,它工作得很好。

我解决了自己的问题。为了每个人的利益,这里是我的结果代码。如果其大于补偿截断问题的原始值,则从该值中减去一

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));
}

你能提供重现问题的示例代码吗?是的,mod函数就是有问题的代码。对于小于y的每个值,它都可以正常工作,但如果它超过y,则会失败。我将发布一个示例用法。
它将生成一个错误的答案
-答案是什么?我刚刚意识到问题是什么。floor函数不适用于负数,因为我截断它的方式,-3.3的floor将是-3,而实际上应该是-4为什么不直接使用
\u mm\u floor\u ps
?你需要支持没有SSE4的旧CPU吗?这个版本仍然有问题;它将为您提供楼层(-1)=-2,这是您不想要的。相反,如果
a
@StephenCanon-Oops,则有条件地减去1。我想我的测试不够彻底。我根据你的建议编辑了我的代码,现在它可以正常工作了。答案也经过了编辑。