[Rcpp-devel] Cost of function pointer dereferencing

romain at r-enthusiasts.com romain at r-enthusiasts.com
Thu Dec 23 19:03:43 CET 2010


Le 23 déc. 2010 à 06:54 PM, Davor Cubranic <cubranic at stat.ubc.ca> a écrit :

> I tried using a functor, calling 'exp' in its operator(), and it was even faster than static (albeit very slightly):

Intriguing.

>      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.

My plan is to go through macros

> Davor
> 
> 
> On 2010-12-23, at 8:45 AM, <romain at r-enthusiasts.com> <romain 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/rcpp-devel
> 


More information about the Rcpp-devel mailing list