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

inf*_*047 8 c++ performance mingw function 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;
}
Run Code Online (Sandbox Code Playgroud)

它在我的电脑上运行5.5秒.但是,如果我改变sqrtstd::sqrt,它将仅0.7秒运行.

我知道,如果我使用sqrt,我正在使用C库中的函数,如果我使用std::sqrt,我正在使用它<cmath>.

<cmath>没有定义一个int,如果我改变的类型i进入double,他们会为相同的速度运行.所以编译器没有优化int.这似乎只发生sqrt在Windows中.

那么为什么std::sqrtsqrt其他功能快得多?为什么在Linux中他们不是?

man*_*lio 7

这是-fdump-tree-*交换机可以对正在发生的事情有所了解的典型情况:

g++ -fdump-tree-optimized example1.cc
Run Code Online (Sandbox Code Playgroud)

你得到的example1.cc.165t.optimized文件.在某处:

<bb 3>:
_5 = (double) i_2;
_6 = sqrt (_5);
sum_7 = sum_1 + _6;
i_8 = i_2 + 1;
Run Code Online (Sandbox Code Playgroud)

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

更换sqrtstd::sqrt你得到的是:

<bb 3>:
_5 = std::sqrt<int> (i_2);
sum_6 = sum_1 + _5;
i_7 = i_2 + 1;
Run Code Online (Sandbox Code Playgroud)

现在它对整数使用不同的sqrt重载(i_2is intsum_6is double).

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

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

在Windows(MinGW)下,这是因为sqrt(double)调用msvcrt而不同.