C++ 有没有一种很好的方法可以用SSE求两个变量的模?(没有SVML)

C++ 有没有一种很好的方法可以用SSE求两个变量的模?(没有SVML),c++,sse,C++,Sse,我正在尝试学习使用SSE,我制作的一个程序需要使用模除法,所以我写了这个来实现它(很抱歉,它被过度使用了): 问题是,这大约与在发行版中分别获取四个32位整数的每个元素的模一样快,而在调试(通过分析发现)中大约慢10倍 有谁能给我一些关于如何使这个函数更快的建议吗 -我不能使用SVML,因为我使用Visual Studio-来处理输入和除数的常规值对于整数除法或模,没有有用的SIMD x86指令,所以最好使用标量整数除法。但是,在某些特殊情况下,SIMD整数模可以更快地完成 例如,如果要执行(a

我正在尝试学习使用SSE,我制作的一个程序需要使用模除法,所以我写了这个来实现它(很抱歉,它被过度使用了):

问题是,这大约与在发行版中分别获取四个32位整数的每个元素的模一样快,而在调试(通过分析发现)中大约慢10倍

有谁能给我一些关于如何使这个函数更快的建议吗


-我不能使用SVML,因为我使用Visual Studio-

来处理
输入
除数的常规值
对于整数除法或模,没有有用的SIMD x86指令,所以最好使用标量整数除法。但是,在某些特殊情况下,SIMD整数模可以更快地完成


例如,如果要执行(a+b)%c以及a和b已减少(即,
a您看过了吗?不确定模运算是一种加速运算,尽管除数在一般情况下都是不同的值,还是它们通常都是相同的值?我看过YEPP,它不提供模函数……事实上,它似乎没有提供英特尔内部函数以外的任何东西,它更快吗除数是可变的,所以我不能做任何快速和肮脏的比特技巧,也不能基于它们是常数来查找表。抱歉-只是100%清楚-我的意思是,对于给定的函数调用,向量中的所有除数值都是相同的值吗?例如,它是
{11,12,13,14,}MOD 7,7,7}
还是更一般的情况,例如
{11,12,13,14,}MOD{6,7,8,9}
__m128i SSEModDiv(__m128i input, __m128i divisors)
{
    //Error Checking (div by zero)
    /*__m128i zeros = _mm_set1_epi32(0);
    __m128i error = _mm_set1_epi32(-1);
    __m128i zerocheck = _mm_cmpeq_epi32(zeros, divisors);
    if (_mm_extract_epi16(zerocheck, 0) != 0)
        return error;
    if (_mm_extract_epi16(zerocheck, 2) != 0)
        return error;
    if (_mm_extract_epi16(zerocheck, 4) != 0)
        return error;
    if (_mm_extract_epi16(zerocheck, 6) != 0)
        return error;*/

    //Now for the real work
    __m128 inputf = _mm_cvtepi32_ps(input);
    __m128 divisorsf = _mm_cvtepi32_ps(divisors);

    /*__m128 recip = _mm_rcp_ps(divisorsf); //Takes reciprocal
    __m128 divided = _mm_mul_ps(inputf, recip); //multiplies by reciprical values*/
    __m128 divided = _mm_div_ps(inputf, divisorsf);
    __m128i intermediateint = _mm_cvttps_epi32(divided); //makes an integer version truncated
    __m128 intermediate = _mm_cvtepi32_ps(intermediateint);
    __m128 multiplied = _mm_mul_ps(intermediate, divisorsf); //multiplies the intermediate with the divisors
    __m128 mods = _mm_sub_ps(inputf, multiplied); //subtracts to get moduli
    return _mm_cvtps_epi32(mods);
}
z = a + b
if(z>=c) z-=c;
float fact = 1.0/x;
for(int i=0; i<n; i++) {
    z[i] = fact*y[i];  //z[i] = y[i]/x;
}
y / x ≈ y * (2 n / x) >> n
for(int i=0; i<n; i++) {
    z[i] = y[i]%x[i];
}