【问题标题】:Rcpp and move semanticRcpp 和移动语义
【发布时间】:2016-02-04 01:50:43
【问题描述】:

我在C++ 中实现了一个算法,它返回一个巨大的元素数组作为输出。现在,我想在Rcpp 中实现一个包装器,这样我就可以使用R 调用这个函数。

我在 Makevars 文件中指定了以下设置:

PKG_CXXFLAGS = -std=c++11

这样我就可以使用C++11版本了。

// [[Rcpp::export]]
NumericMatrix compute(int width, int height)
{
  vector<data_t> weights(width * height);
  compute_weights(weights);

  NumericMatrix mat(height, width);
  copy(begin(weights), end(weights), mat.begin());

  return mat;
}

如果函数返回时移动了 NumericMatrix,则上述包装函数仍然有效,否则将创建一个新对象。

Rcpp 是否利用了移动语义?如果没有,是否有任何解决方法可以避免构建副本?

【问题讨论】:

  • 我对 rcpp 一无所知,但如果您需要解决方法,我相信它不会按值返回。
  • 这应该 NRVO 在任何体面的编译器上,移动语义与否。
  • 尽管有 NRVO,移动语义不是 Rcpp 的一部分。他们是你班级的一部分。您的 NumericMatrix 是否有右值引用构造函数?如果是这样,任何符合标准的编译器都会调用它。
  • @SergeyA NumericMatrix 是一个 Rcpp 类,不是我的。这就是我要问的。
  • 引用 Romain 的评论 here“Rcpp 没有为 Rcpp 类实现移动语义。编译器自动生成的移动构造函数或赋值运算符可能不会做正确的事情。” 。另外,请注意,您可以指定属性// [[Rcpp::plugins(cpp11)]],作为编辑Makevars 的较少干扰的替代方法。

标签: c++ c++11 rcpp move-semantics


【解决方案1】:

如果函数返回时移动了 NumericMatrix,则上述包装函数仍然有效,否则将创建一个新对象。

...如果没有,是否有任何解决方法可以避免构建副本?

我认为拷贝构造函数只创建了一个浅拷贝,所以不应该有任何拷贝。请参阅Rcpp: How to ensure deep copy of a NumericMatrix?

这个例子也证实了这一点

#include <Rcpp.h>

// [[Rcpp::export]]
Rcpp::NumericVector allocate_the_vec(R_xlen_t n_ele){
  Rcpp::NumericVector out(n_ele);
  return out;
}

/*** R
# got 16 GB ram on my laptop. 3 x 7 is an issue but 2 x 7 is not
how_large <- as.integer(7 * 10^9 / 8)
the_large_vec_1 <- allocate_the_vec(how_large)
object.size(the_large_vec_1)
the_large_vec_2 <- allocate_the_vec(how_large)
*/

【讨论】:

    猜你喜欢
    • 2020-08-20
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-12
    • 2013-02-11
    相关资源
    最近更新 更多