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_单调,…)