I am running the exact same code in two ways: compiling it with the g++
compiler, and calling it from R
with Rcpp
. It turns out that it runs almost 4 times faster when I run it through R
.
Why does this happen? Is it because the compiler used by Rcpp
is different?
This is the code I'm running in c++
:
#include <iostream>
#include <nlopt.hpp>
#include <time.h>
using namespace std;
int main()
{
//--------------------------------//
// Initialization //
//--------------------------------//
// Grid for x
const int nx = 60000;
float xgrid[nx];
const float xstep = 4 /(nx - 1);
float it = 0;
for(int i = 0; i < nx; i++){
xgrid[i] = it*xstep;
it++;
}
// Initialize value function V
size_t sizeV = nx*sizeof(float);
float *V;
V = (float *)malloc(sizeV);
//--------------------------------//
// Computation //
//--------------------------------//
// Variables for computation time
double t0 = clock();
double t = t0;
float utility;
float VV = pow(-10.0,5.0);
for(int ix = 0; ix<nx; ix++){
VV = pow(-10.0,5.0);
for(int ixp = 0; ixp < nx; ixp++){
utility = (xgrid[ix] + 1 - xgrid[ixp])*(xgrid[ix] + 1 - xgrid[ixp]);
if(utility >= VV){
VV = utility;
}
}
V[ix] = VV;
}
t = clock() - t0;
cout << "Time: " << ((float)t)/CLOCKS_PER_SEC << " seconds." << endl;
return 0;
}
To run it I use:
g++ Cpp_main.cpp -o Cpp_main
The code in Rcpp
is:
#include <iostream>
#include <nlopt.hpp>
#include <time.h>
using namespace std;
// [[Rcpp::export]]
vector<double> value(int nx){
//--------------------------------//
// Grid creation //
//--------------------------------//
float xgrid[nx];
const float xstep = 4 /(nx - 1);
float it = 0;
for(int i = 0; i < nx; i++){
xgrid[i] = it*xstep;
it++;
}
// Initialize value function V
vector<double> V;
V.resize(nx);
//--------------------------------//
// Computation //
//--------------------------------//
// Variables for computation time
double t0 = clock();
double t = t0;
float utility;
float VV = pow(-10.0,5.0);
for(int ix = 0; ix<nx; ix++){
VV = pow(-10.0,5.0);
for(int ixp = 0; ixp < nx; ixp++){
utility = (xgrid[ix] + 1 - xgrid[ixp])*(xgrid[ix] + 1 - xgrid[ixp]);
if(utility >= VV){
VV = utility;
}
}
V[ix] = VV;
}
t = clock() - t0;
cout << "Time: " << ((float)t)/CLOCKS_PER_SEC << " seconds." << endl;
return V;
}
And I call it from R
with:
library("Rcpp")
sourceCpp("Rcpp_main.cpp")
# Grid for x
nx = 60000;
V = value(nx);
The running time in c++
is twice the running time in Rcpp
. Any clues why this happens?
Just looking your main()
we get this:
edd@rob:/tmp/soQ$ g++ -o main main.cpp
edd@rob:/tmp/soQ$ ./main
Time: 8.42708 seconds.
edd@rob:/tmp/soQ$ g++ -o main -O3 -march=native main.cpp
edd@rob:/tmp/soQ$ ./main
Time: 1.59151 seconds.
edd@rob:/tmp/soQ$
That is already a factor of 5.3, and one of the weirdest examples I have seen in some time for the impact of -O3
.
For R, I get about the same time as R defaults to using -O3 here too.
R> Rcpp::sourceCpp("/tmp/soQ/rcppfunction.cpp")
R> V <- value(60000)
Time: 1.65224 seconds.
R>
So no real mistery here. You used different options, and it mattered.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With