在一些旧的src代码中找到以下行:
int e = (int)fmod(matrix[i], n);
其中matrix
是int
的数组,而n
是size_t
我想知道为什么使用fmod
而不是%
我们有整数参数,为什么不呢:
int e = (matrix[i]) % n;
选择fmod
超过%
可能有性能原因,还是仅仅是一段奇怪的代码?
答案 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] % n
和n == 0
上的行为。整数模运算在溢出时调用未定义的行为,这导致许多当前体系结构上的程序异常终止。相反,浮点模数没有这些极端情况,结果为INT_MIN % -1
,+Infinity
,-Infinity
,具体取决于Nan
和matrix[i]
的值,所有超出范围-INT_MIN
并且转换回int
是实现定义的,但通常不会导致程序异常终止。这可能是原始程序员选择这种令人惊讶的解决方案的原因。