[Rcpp-devel] Cost of function pointer dereferencing
Davor Cubranic
cubranic at stat.ubc.ca
Fri Dec 24 18:26:11 CET 2010
Thanks for prompting me to start experimenting with inline and finer
points of C++! It's something I've wanted to do for a while. I'm glad
you find it useful, this whole template stuff is still pretty new to me.
Davor
On December 24, 2010 03:08:36 am romain at r-enthusiasts.com wrote:
> Thanks. I'll use that.
>
> Le jeu 23/12/10 22:51, "Davor Cubranic" cubranic at stat.ubc.ca a écrit:
> > After a bit of googling, I figured out how to write the templated
> > functor. It's very simple:
> > incw <- '
> > template<double Func(double) >
> > struct Ftor {
> > inline double operator () (double x) const {
> > return Func(x);
> > }
> > };
> > Ftor<exp> ftor;
> > '
> > fw <- cxxfunction( , '
> > double x ;
> > for( int j=0; j<1000; j++){
> > for( int i=0; i<1000000; i++){
> > x = ftor(2.0) ;
> > }
> > }
> > return wrap( x ) ;
> > ', plugin = "Rcpp", includes = incw , verbose=TRUE)
> >
> > And it's still (insignificantly) faster than the static call:
> >
> > test replications elapsed relative user.self sys.self user.child
> > 3 functor 1 0.463 1.000000 0.464 0.001
> > 0 1 static 1 0.468 1.010799 0.464 0.000
> > 0 2 pointer 1 15.960 34.470842 15.824 0.017
> > 0
> >
> > Davor
> >
> > On 2010-12-23, at 9:54 AM, Davor Cubranic wrote:
> > > I tried using a functor, calling 'exp' in its
> >
> > operator(), and it was even faster than static (albeit very
> >
> > slightly):
> > > test replications elapsed relative user.self
> >
> > sys.self user.child
> > 3 functor 1 0.465 1.000000 0.464
> >
> > 0.000 0
> >
> > 1 static 1 0.472 1.015054 0.464
> >
> > 0.001 0
> >
> > 2 pointer 1 15.855 34.096774 15.815
> >
> > 0.007 0
> >
> > > Just add 'fw' below to your benchmark:
> > >
> > > incw <- '
> > >
> > > class Ftor {
> > >
> > > public:
> > > inline double operator () (double x) const
> >
> > {
> >
> > return exp(x);
> >
> > > }
> > >
> > > };
> > > const Ftor ftor = Ftor();
> > >
> > > '
> > > fw <- cxxfunction( , '
> > > double x ;
> > > for( int j=0; j<1000; j++){
> > > for( int i=0; i<1000000; i++){
> > >
> > > x = ftor(2.0) ;
> > >
> > > }
> > > }
> > > return wrap( x ) ;
> > > ', plugin = "Rcpp", includes = incw ,
> >
> > verbose=TRUE)
> >
> > > Maybe you could create a functor for each basic
> >
> > function and use that in a common loop implementation.
> >
> > > I also tried templatizing Ftor on the function it
> >
> > delegates to, so that you could do something like Ftor<exp>(), but
> > I couldn't get it to compile. Your template-fu is far better than
> > mine, so maybe you'll be able to wrangle it into shape and have
> > even more succint code.
> >
> > > Davor
> > >
> > >
> > > On 2010-12-23, at 8:45 AM, <roma
> >
> > in at r-enthusiasts.com> <roma
> >
> > in at r-enthusiasts.com> wrote:
> > >> Hello,
> > >>
> > >> Since I've been playing with efficiency of
> >
> > various operators for numeric vectors (+,-,/,*), I'm now looking at
> > other functions such as exp, sqrt, etc ...
> >
> > >> The way we currently implement exp for vectors
> >
> > requires that we keep a function pointer for the atomic exp and
> > that we dereference the function pointer each time. It turns out
> > that this has some
> >
> > cost :
> > >> test replications elapsed relative user.self
> >
> > sys.self user.child sys.child
> >
> >> 1 static 1 0.691 1.00000
> >
> > 0.691 0.000 0 0
> >
> >> 2 pointer 1 11.157 16.14616
> >
> > 11.144 0.012 0 0
> >
> > >> Reproduced by this code:
> > >>
> > >> require( Rcpp )
> > >> require( inline )
> > >>
> > >> fx <- cxxfunction( , '
> > >> double x ;
> > >> for( int j=0; j<1000; j++){
> > >> for( int i=0; i<1000000; i++){
> > >>
> > >> x = exp(2.0) ;
> > >>
> > >> }
> > >> }
> > >> return wrap( x ) ;
> > >> ', plugin = "Rcpp" )
> > >>
> > >> inc <- '
> > >>
> > >> double (*fun)(double) = exp ;
> > >>
> > >> '
> > >> fy <- cxxfunction( , '
> > >> double x ;
> > >> for( int j=0; j<1000; j++){
> > >> for( int i=0; i<1000000; i++){
> > >>
> > >> x = (*fun)(2.0) ;
> > >>
> > >> }
> > >> }
> > >> return wrap( x ) ;
> > >> ', plugin = "Rcpp", includes = inc )
> > >>
> > >>
> > >> require( rbenchmark )
> > >> benchmark(
> > >>
> > >> order = "relative",
> > >> static = fx(),
> > >> pointer = fy(),
> > >> replications = 1L
> > >>
> > >> )
> > >>
> > >> Romain
> >
> > _______________________________________________
> >
> >> Rcpp-devel mailing list
> >>
> > >> Rcpp-devel at lists.r-forge.r-project.org
> >>
> >> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rc
> >
> > pp-devel
> >
> >
> > _______________________________________________
> > Rcpp-devel mailing list
> >
> > > Rcpp-devel at lists.r-forge.r-project.org
> >
> > https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rc
> > pp-devel
More information about the Rcpp-devel
mailing list