gcc不同的优化选项运行结果还不一样(nan在搞鬼)

最近编译protobuf遇到一个奇葩事儿,修改了一下编译优化选项,把-O3改成了-Ofast,居然程序运行的结果还不一致了,这让我非常意外。找来找去,发现是NaN在搞鬼。

NaN对于float或者double是一个特殊的存在,如何判断一个float/double是不是NaN呢,方法也很特别,就是NaN跟NaN是不相等的,就像无穷大不能比大小一样。所以实现是这样的:

inline bool IsNaN(double value) {
  // NaN is never equal to anything, even itself.
  return value != value;
}

在math.h里也有这样一个函数叫isnan(),估计实现也是一个原理。有趣的是,这种写法,估计就把编译弄晕了,导致一优化结果就不对了。

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

int main()
{
    float f = NAN;
    printf("%f %d %d\n", f, isnan(f), f == f);
    return 0;
}

上面的代码执行结果就很奇葩:

nan 1 0  //-O0
nan 1 0  //-Os
nan 0 1 //-Ofast
nan 1 0 //-O3

通常来说,我们把-Ofast认为是专门考虑性能的优化。很奇怪的是,它这结果跟-O3反而不同的,网上有个说法是,-Ofast使用了FastMath,就导致为了计算速度不那么精准了。

发表于 2018年11月30日 15:03   评论:0   阅读:3083  



回到顶部

首页 | 关于我 | 关于本站 | 站内留言 | rss
python logo   django logo   tornado logo