使用 Rcpp 的代码比使用 g++ 编译的代码运行得更快
Code runs faster with Rcpp than compiled with g++
我 运行 以两种方式编写完全相同的代码:使用 g++
编译器编译它,并使用 Rcpp
从 R
调用它。事实证明,当我 运行 通过 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>
所以这里没有真正的谜团。您使用了不同的选项,这很重要。
我 运行 以两种方式编写完全相同的代码:使用 g++
编译器编译它,并使用 Rcpp
从 R
调用它。事实证明,当我 运行 通过 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>
所以这里没有真正的谜团。您使用了不同的选项,这很重要。