为什么全局范围内的sqrt比MinGW中的std :: sqrt慢得多?

时间:2014-10-24 11:35:07

标签: c++ performance function mingw sqrt

请考虑以下代码:

#include <cmath>
#include <cstdio>

const int COUNT = 100000000;

int main()
{
    double sum = 0;
    for (int i = 1; i <= COUNT; ++i)
        sum += sqrt(i);
    printf("%f\n", sum);
    return 0;
}

它在我的电脑上运行5.5秒。但是,如果我将sqrt更改为std::sqrt,它将只运行0.7秒。

我知道如果我使用sqrt,我会使用C库中的函数,如果我使用std::sqrt,我会使用{{1}中的函数}。

但是<cmath>没有为<cmath>定义一个,如果我将int的类型更改为i,它们将以相同的速度运行。因此编译器不会针对double进行优化。这似乎只发生在Windows中的int

那么为什么sqrtstd::sqrt快得多,而不是其他功能呢?为什么在Linux中他们不是?

1 个答案:

答案 0 :(得分:6)

这是典型情况,-fdump-tree-*转换可以让您了解正在发生的事情:

g++ -fdump-tree-optimized example1.cc

您将获得example1.cc.165t.optimized文件。在某处:

<bb 3>:
_5 = (double) i_2;
_6 = sqrt (_5);
sum_7 = sum_1 + _6;
i_8 = i_2 + 1;

编译器(gcc v4.8.3)正在使用double进行数学运算。

sqrt取代std::sqrt获得的是:

<bb 3>:
_5 = std::sqrt<int> (i_2);
sum_6 = sum_1 + _5;
i_7 = i_2 + 1;

现在它对整数使用不同的sqrt重载(i_2intsum_6double)。

正如Mike Seymour在comment中所说,无论你是否指定C ++ 11,GCC都会使用新的重载。

无论如何,在Linux下,两种实现之间没有明显的性能差异。

在Windows(MinGW)下,这与sqrt(double) calls into msvcrt相同。