使用 Rcpp 的代码比使用 g++ 编译的代码运行得更快

Code runs faster with Rcpp than compiled with g++

我 运行 以两种方式编写完全相同的代码:使用 g++ 编译器编译它,并使用 RcppR 调用它。事实证明,当我 运行 通过 R 时,它 运行 几乎快了 4 倍。

为什么会这样?是因为Rcpp使用的编译器不一样吗?

这是我 运行 在 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;
}

我用运行它:

g++ Cpp_main.cpp -o Cpp_main

Rcpp中的代码是:

#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;
}

我从 R 调用它:

library("Rcpp")
sourceCpp("Rcpp_main.cpp")

# Grid for x
nx            = 60000; 

V = value(nx);

运行c++中的宁时间是Rcpp中运行宁时间的两倍。为什么会发生这种情况的任何线索?

看看你的 main() 我们就知道了:

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$ 

这已经是 5.3 的一个因素,也是我一段时间以来看到的关于 -O3 影响的最奇怪的例子之一。

对于 R,我得到大约相同的时间因为 R 在这里也默认使用 -O3

R> Rcpp::sourceCpp("/tmp/soQ/rcppfunction.cpp")    
R> V <- value(60000)
Time: 1.65224 seconds.    
R>  

所以这里没有真正的谜团。您使用了不同的选项,这很重要。