下面的parallelFor玩具示例很好(f2是f1的并行版本):
// [[Rcpp::depends(RcppParallel)]]
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include <iostream>
#define vector NumericVector
using namespace Rcpp;
using namespace RcppParallel;
// compute values i/i+1 for i = 0 to n-1
// [[Rcpp::export]]
vector f1(int n) {
vector x(n);
for(int i = 0; i < n; i++) x[i] = (double) i/ (i+1);
return x;
}
struct mytry : public Worker {
vector output;
mytry(vector out) : output(out) {}
void operator()(std::size_t begin, std::size_t end) {
for(int i = begin; i < end; i++) output[i] = (double) i/ (i+1);
}
};
// [[Rcpp::export]]
vector f2(int n) {
vector x(n);
mytry A(x);
parallelFor(0, n, A);
return x;
}但是,如果我将#define vector NumericVector替换为#define vector arma::vec,则不再起作用。代码编译并运行,f1是好的,但是f2返回的向量只包含未初始化的值。
非常感谢您的任何澄清。
发布于 2014-10-08 17:21:00
这里的问题是--你的课应该是参考向量,而不是价值向量。
这是因为,在使用RcppParallel时,您通常会为某个对象预先分配内存,然后填充该对象--所以并行工作人员应该引用要填充的对象。
因此,您的员工应该看起来像(正如您已经注意到的):
struct mytry : public Worker {
vector& output;
mytry(vector& out) : output(out) {}
void operator()(std::size_t begin, std::size_t end) {
for(int i = begin; i < end; i++) output[i] = (double) i/ (i+1);
}请注意,这对于Rcpp向量是可行的(也许令人惊讶),因为它们已经是‘代理’对象--只是封装了指向数据的指针的对象。通过值传递Rcpp向量时,可以复制指针(而不是底层数据!)加上一些额外的向量位(例如向量的长度) --因此“复制”保留了对相同数据结构的引用。
当您使用更“经典”的向量(例如arma::vec或std::vector )时,当按值将该向量传递给工作人员时,您实际上是在将一个全新的向量复制到类中,然后填充该向量(临时的、复制的)向量--因此原始向量实际上永远不会被填充。
https://stackoverflow.com/questions/26234055
复制相似问题