对于整数模数计算,fmod是否快于%

时间:2017-01-16 21:10:37

标签: c integer modulus

在一些旧的src代码中找到以下行:

int e = (int)fmod(matrix[i], n);

其中matrixint的数组,而nsize_t

我想知道为什么使用fmod而不是%我们有整数参数,为什么不呢:

int e = (matrix[i]) % n;

选择fmod超过%可能有性能原因,还是仅仅是一段奇怪的代码?

3 个答案:

答案 0 :(得分:2)

  

选择fmod超过%可能有性能原因   或者它只是一个奇怪的代码?

fmod在具有高延迟IDIV指令的架构上可能会快一点,需要(比方说)~50个周期或更多,因此fmod的功能来电和int <---> double转化费用可以摊销。

根据Agner's Fog instruction tables,AMD K10架构上的IDIV需要24-55个周期。与现代英特尔Haswell相比,其延迟范围列为22-29个周期,但如果没有依赖链,则在英特尔的8-11个时钟周期内,相对吞吐量要好得多。

答案 1 :(得分:1)

实验(并且非常直观地),fmod%更快 - 至少在 AMD Phenom(tm)II X4 955(6400 bogomips )上更快。下面是两个使用这两种技术的程序,它们都使用相同的编译器(GCC)和相同的选项(cc -O3 foo.c -lm编译),并在同一硬件上运行:

#include <math.h>
#include <stdio.h>

int main()
{
    int volatile a=10,b=12;
    int i, sum = 0;
    for (i = 0; i < 1000000000; i++)
        sum += a % b;
    printf("%d\n", sum);
    return 0;
}

运行时间:9.07秒

#include <math.h>
#include <stdio.h>

int main()
{
    int volatile a=10,b=12;
    int i, sum = 0;
    for (i = 0; i < 1000000000; i++)
        sum += (int)fmod(a, b);
    printf("%d\n", sum);
    return 0;
}

运行时间:8.04秒

答案 2 :(得分:1)

dispatch可能比选定体系结构上的整数除法快一点。

但是请注意,如果fmod在编译时具有已知的非零值,n将被编译为带有小调整的乘法,这应该比整数模数和浮点模数。

另一个有趣的区别是matrix[i] % nn == 0上的行为。整数模运算在溢出时调用未定义的行为,这导致许多当前体系结构上的程序异常终止。相反,浮点模数没有这些极端情况,结果为INT_MIN % -1+Infinity-Infinity,具体取决于Nanmatrix[i]的值,所有超出范围-INT_MIN并且转换回int是实现定义的,但通常不会导致程序异常终止。这可能是原始程序员选择这种令人惊讶的解决方案的原因。