gpt4 book ai didi

c++ - 为什么 GCC 对 C++ 比 C 更有效地实现 isnan()?

转载 作者:IT老高 更新时间:2023-10-28 14:01:25 26 4
gpt4 key购买 nike

这是我的代码:

int f(double x)
{
return isnan(x);
}

如果我 #include <cmath>我得到了这个程序集:

xorl    %eax, %eax
ucomisd %xmm0, %xmm0
setp %al

这相当聪明:ucomisd如果 x 与自身的比较是无序的,则设置奇偶校验标志,这意味着 x 是 NAN。那么setp将奇偶校验标志复制到结果中(只有一个字节,因此 %eax 的初始清除)。

但是如果我 #include <math.h>我得到了这个程序集:

jmp     __isnan

现在代码不是内联的,__isnan功能肯定是没有快的ucomisd指令,所以我们已经引起了无益的跳跃。如果我将代码编译为 C,我会得到同样的结果。

现在,如果我更改 isnan()调用__builtin_isnan() ,我得到了简单的 ucomisd指令指令,无论我包含哪个 header ,它也适用于 C 语言。同样,如果我只是 return x != x .

所以我的问题是,为什么 C <math.h> header 提供了 isnan() 的效率较低的实现比 C++ <cmath>标题?人们真的期望使用__builtin_isnan() ,如果是,为什么?

我使用 -O2 在 x86-64 上测试了 GCC 4.7.2 和 4.9.0和 -O3优化。

最佳答案

<cmath>对于 gcc 4.9 附带的 libstdc++,您会得到:

  constexpr bool
isnan(double __x)
{ return __builtin_isnan(__x); }

一个 constexpr函数可以积极内联,当然,该函数只是将工作委托(delegate)给 __builtin_isnan .

<math.h> header 不使用 __builtin_isnan ,而是使用 __isnan在这里粘贴的实现有点长,但它是 math.h 的第 430 行在我的机器上™。由于 C99 标准要求对 isnan 使用宏等(C99 标准的第 7.12 节)“功能”定义如下:

#define isnan(x) (sizeof (x) == sizeof (float) ? __isnanf (x)   \
: sizeof (x) == sizeof (double) ? __isnan (x) \
: __isnanl (x))

但是,我看不出它为什么不能使用 __builtin_isnan而不是 __isnan所以我怀疑这是一个疏忽。正如 Marc Glisse 在评论中指出的那样,有一个 relevant bug report对于类似的问题,使用 isinf而不是 isnan .

关于c++ - 为什么 GCC 对 C++ <cmath> 比 C <math.h> 更有效地实现 isnan()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26052640/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com