这是我的代码:
int f(double x)
{
return isnan(x);
}
如果我#include <cmath>
得到这个程序集:
xorl %eax, %eax
ucomisd %xmm0, %xmm0
setp %al
这是相当聪明的:如果 x 与自身的比较是无序的,则ucomisd设置奇偶校验标志,这意味着 x 是 NAN。然后setp将奇偶校验标志复制到结果中(只有一个字节,因此初始清除%eax
)。
但如果我#include <math.h>
得到这个程序集:
jmp __isnan
现在代码没有内联了,__isnan
函数肯定没有快了ucomisd
指令快,所以我们进行了一次跳转,没有任何好处。如果我将代码编译为 C,我会得到同样的结果。
现在,如果我将isnan()
调用更改为,无论我包含哪个标头__builtin_isnan()
,我都会得到简单的指令指令,并且它也可以在 C 中使用。ucomisd
同样,如果我只是return x != x
.
所以我的问题是,为什么 C<math.h>
头文件提供的实现效率isnan()
低于 C++<cmath>
头文件?人们真的期望使用__builtin_isnan()
,如果是,为什么?
我在 x86-64 上使用-O2
和-O3
优化测试了 GCC 4.7.2 和 4.9.0。