C++ llvm g++;和升压功能

C++ llvm g++;和升压功能,c++,g++,llvm,boost-function,C++,G++,Llvm,Boost Function,我试图确定与使用函数模板相比,计算数学函数所带来的时间开销是否可以忽略 我使用的基准测试代码如下 对于传统的g++,boost::function的开销可以忽略: $ g++ -O3 main.cxx $ ./a.out METHOD INTEGRAL TIME TO COMPUTE (SEC) Direct 0.379885 3.360000 Function templat

我试图确定与使用
函数模板相比,计算数学函数所带来的时间开销是否可以忽略

我使用的基准测试代码如下

对于传统的
g++
,boost::function
的开销可以忽略:

$ g++ -O3 main.cxx 
$ ./a.out
METHOD              INTEGRAL  TIME TO COMPUTE (SEC)         
Direct              0.379885  3.360000                      
Function template   0.379885  3.380000                      
Boost function      0.379885  3.400000   
使用
llvm-g++
,模板函数
的速度增加系数为1.5,而
boost::函数
的速度增加系数为1.5

$ llvm-g++ -O3 main.cxx
METHOD              INTEGRAL  TIME TO COMPUTE (SEC)         
Direct              0.379885  2.170000                      
Function template   0.379885  2.160000                      
Boost function      0.379885  3.360000    
对于
boost::function
llvm-g++
,是否可能获得1.5增益

#include <boost/function.hpp>
#include <math.h>
#include <stdio.h>

typedef unsigned int UInt;

using namespace std;

//=============================================================================
// chrono
//=============================================================================
class Chrono
{
    clock_t t1_,t2_,dt_;
    public:
        Chrono(){}
        void   start() { t1_=clock(); };
        void   stop()  { t2_=clock(); };
        double diff()  { return ( (double)( t2_ - t1_) ) / CLOCKS_PER_SEC; };
};

//=============================================================================
// function to integrate
//=============================================================================
inline double fct(double x)
{
    return 1. / (1.+exp(x));
}

//=============================================================================
// using direct method
//=============================================================================
double direct(double a, double b, UInt numSamplePoints)
{
    double delta = (b-a) / (numSamplePoints-1);
    double sum = 0.;
    for (UInt i=0; i < numSamplePoints-1; ++i)
        sum += 1. / (1. + exp(a + i*delta));
    return sum * delta;
}

//=============================================================================
// using function template
//=============================================================================
template<double functionToIntegrate(double)>
double integrate(double a, double b, UInt numSamplePoints)
{
    double delta = (b-a) / (numSamplePoints-1);
    double sum = 0.;
    for (UInt i=0; i < numSamplePoints-1; ++i)
        sum += functionToIntegrate(a + i*delta);
    return sum * delta;
}

//=============================================================================
// using Boost function
//=============================================================================
typedef boost::function<double ( double )> fct_type;

class IntegratorBoost {
    public:
    fct_type functionToIntegrate;
    IntegratorBoost(fct_type fct): functionToIntegrate(fct){}
    double integrate(double a, double b, UInt numSamplePoints)
    {
        double delta = (b-a) / (numSamplePoints-1);
        double sum = 0.;
        for (UInt i=0; i < numSamplePoints-1; ++i)
        sum += functionToIntegrate(a + i*delta);
        return sum * (b-a) / numSamplePoints;
    }
};

//=============================================================================
// main
//=============================================================================
int main()
{
    double integral;
    UInt numSamplePoints = 5E07;
    Chrono chrono;

    printf("%-20s%-10s%-30s\n","METHOD","INTEGRAL","TIME TO COMPUTE (SEC)");

    // Direct
    chrono.start();
    integral = direct(0., 1., numSamplePoints);
    chrono.stop();
    printf("%-20s%-10f%-30f\n","Direct",integral,chrono.diff());

    // Function template
    chrono.start();
    integral = integrate<fct>(0., 1.,numSamplePoints);
    chrono.stop();
    printf("%-20s%-10f%-30f\n","Function template",integral,chrono.diff());

    // Boost function
    chrono.start();
    IntegratorBoost intboost(fct);
    integral = intboost.integrate(0.,1.,numSamplePoints);
    chrono.stop();
    printf("%-20s%-10f%-30f\n","Boost function",integral,chrono.diff());
}
#包括
#包括
#包括
typedef无符号整数单元;
使用名称空间std;
//=============================================================================
//计时
//=============================================================================
类计时
{
时钟t1,t2,dt;
公众:
Chrono(){}
void start(){t1=时钟();};
void stop(){t2=时钟();};
double diff(){return((double)(t2_-t1_))/CLOCKS_PER_secs;};
};
//=============================================================================
//功能整合
//=============================================================================
内联双fct(双x)
{
返回1./(1.+exp(x));
}
//=============================================================================
//直接法
//=============================================================================
双直接(双a、双b、UInt numSamplePoints)
{
双增量=(b-a)/(numSamplePoints-1);
双和=0。;
对于(UInt i=0;i
如果不进行实际测量,我将冒险宣称使用
boost::function
(或C++11中的
std::function
)不能像其他两个选项那样有效

原因是
function
使用类型擦除来删除正在使用的实际functor的类型,这意味着
function
需要存储通过指针进行调用的实际对象,并使用函数调用。另一方面,在其他两种方法中,编译器能够内联逻辑并消除调度成本

<>这与C语言库<代码> qStase<代码>的性能差异与C++ + > >排序< /代码>非常相似,在这里,使用函子编译器有更好的内联和优化的机会。
另一个问题是,这是否会对您的应用程序产生影响,您需要对此进行衡量。在这种情况下,IO或任何其他操作的总体成本可能会主导您的应用程序,而这根本不会产生任何影响。

使用
时钟
进行基准测试并不那么可靠。我怀疑它可能会扭曲你的结果,使它们变得毫无意义。在Linux上,我建议使用
gettimeofday
来获得更精确的计时器。此外,llvm-g++已被弃用(并基于g++4.2),我建议切换到Clang3.0,以获得更好的一致性和全新的C++11。我还将对lambda函数计时,看看它的性能如何。它具有
boost::function
和低级编译器支持的所有优点。@MatthieuM。精确计时器的正确功能是clock_gettime(clock_单调,…)