Rcpp / RcppArmadillo性能C ++ / R余额

时间:2016-08-19 14:26:02

标签: c++ r performance rcpp

当我对用RcppArmadillo编写的小块代码/函数进行基准测试时,我看到有时令人难以置信(对于简单操作中的嵌套for循环,为55x vs R)为适度(1.3x vs R,用于长持续时间函数)速度增益。对此印象深刻,我决定翻译大约400行代码来创建一个C ++函数(带有一些小的相邻C ++函数)来替换我的R应用程序的计算密集型主体。

旧结果: RcppArmadillo代码的运行速度比原生R慢3倍(更新 - 可能是一个糟糕的基准测试 - 正在研究它)。混合动力车RcppArmadillo&amp;代码的R变量运行速度比R <。

快1.10倍

更新/经验教训: C ++密集型代码的运行速度比R&amp; C ++混合代码快约6倍。对于任何过路人来说,我犯的错误如下:

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

编辑(对于此帖子上的第一条评论抱歉不合适) 旧问题:

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

任何实用的建议表示赞赏。我为这个模糊的问题道歉,我是SO的新手,是RcppArmadillo软件包的新手,并且在10年内没有编写C ++。

1 个答案:

答案 0 :(得分:2)

  

RcppArmadillo代码比原生R慢〜3倍。混合RcppArmadillo&amp;代码的R变量运行速度比R <。

快1.10倍

你必须要复制很多东西。这根本不合理。也许是时候分析你的代码了吗?

任何发布的示例。也许来自Rcpp画廊,它有多个帖子。也许来自现在使用RcppArmadillo的250(!!)CRAN软件包。从简单的事情开始,并计时。

你应该看到从R转换为C ++的循环的~50x因子。对于纯矢量化代码,您应该看到接近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>