Rcpp/RcppArmadillo c++ /R平衡性能

Rcpp/RcppArmadillo C++/R balance for Performance

本文关键字:平衡性 性能 平衡 c++ RcppArmadillo Rcpp      更新时间:2023-10-16

当我对用RcppArmadillo编写的小块代码/函数进行基准测试时,我有时会看到令人难以置信的(在简单操作中嵌套的for循环比R快55倍)到中等(长时间函数比R快1.3倍)的速度提升。对此印象深刻的是,我决定翻译大约400行代码来创建一个c++函数(加上一些小的c++函数),以取代我的R应用程序中计算密集型的主体。

旧的结果:RcppArmadillo代码的运行速度比原生R慢3倍(更新-可能是一个糟糕的基准测试-正在进行中)。杂交RcppArmadillo &R版本的代码运行速度比R快1.10倍。

更新/经验教训:c++密集型代码的运行速度比r&&c++混合代码快6倍。对于任何路人,我所犯的错误如下:

  • 我没有在我的R基准测试中考虑变量实例化(不公平的比较)。
  • 在一个嵌套的c++循环中放错了一些计算。在R版本中,它们位于所述循环之外(包括大FFT等)。人类错误。
  • 正在传递大量的函数参数(大向量,矩阵,带转换等)。通过移植更多代码解决了这个问题。
  • 我没有有效地处理内存。他们制作了额外的副本,而不是直接使用它们。这些拷贝有助于提高可读性,但可能会损害性能。
  • 使用全局变量来减少函数传递的开销,并从一些计算中删除一些大的临时向量(向量大小:2^15)。

编辑(抱歉与这篇文章的第一条评论不一致)老问题:

  • 是全局变量实例化/初始内存分配建议在RcppArmadillo代码空间,以节省许多变量声明在函数体/R垃圾收集?或者Rcpp是否像R一样及时地处理这些问题?
  • 假设Rcpp由于与R接口(保护变量,垃圾收集等)而失去一些性能,我是否正确?如果是这样,我在哪里可以找到处理这些操作的代码(文件名)/文档,以便我可以学习如何更好地使用它。

感谢任何实用的建议。我为这个模糊的问题道歉,我是SO的新手,RcppArmadillo包的新手,并且已经有10年没有写过c++了。

RcppArmadillo代码的运行速度比本地r慢3倍。R版本的代码运行速度比R快1.10倍。

你一定抄了很多。这种说法根本不可信。也许是时候分析你的代码了?

任何张贴的例子为例。也许从Rcpp画廊有多个帖子。也许从现在的250辆开始(!!)CRAN包使用RcppArmadillo。从简单的事情开始,并计时。

您应该看到循环的~ 50x因子从R转换到c++。对于纯向量化代码,你应该会看到接近1.5倍的速度(因为R倾向于做更多的错误检查,而不是我们在小扩展中编写的代码)。

编辑:这是一个琐碎的基准测试,显示设置一个是多么琐碎。你真的可以(也应该!!)对你认为效率低下的部分进行计时。我们都会犯错误,无论是在设计上还是在执行上。好的是你有工具大量的张贴的例子来指导你。

R> Rfunc <- function(N) { s <- 0; for (i in 1:N) for (j in 1:N) s <- s+1; s }
R> Rfunc(10)
[1] 100
R> 
R> library(Rcpp)
R> cppFunction("double Cppfunc(int N) { double s=0; for (int i=0; i<N; i++) for (int j=0; j<N; j++) s++; return(s); }")
R> Cppfunc(10)
[1] 100
R> 
R> library(rbenchmark)
R> N <- 1000
R> benchmark(Rfunc(N), Cppfunc(N), order="relative")[,1:4]
        test replications elapsed relative
2 Cppfunc(N)          100   0.073    1.000
1   Rfunc(N)          100  12.596  172.548
R>