Vector 使用RcppParallel并行添加向量

Vector 使用RcppParallel并行添加向量,vector,rcpp,rcppparallel,Vector,Rcpp,Rcppparallel,我正在尝试使用RcppParallel并行化(大)向量的加法。这就是我想到的 // [[Rcpp::depends(RcppParallel)]] #include <RcppParallel.h> #include <Rcpp.h> #include <assert.h> using namespace RcppParallel; using namespace Rcpp; // [[Rcpp::export]] NumericVector direct

我正在尝试使用RcppParallel并行化(大)向量的加法。这就是我想到的

// [[Rcpp::depends(RcppParallel)]]
#include <RcppParallel.h>
#include <Rcpp.h>
#include <assert.h> 
using namespace RcppParallel;
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector directVectorAddition(NumericVector first, NumericVector second) {
    assert (first.length() == second.length());
    NumericVector results(first.length());
    results = first + second;
    return results;
}

// [[Rcpp::export]]
NumericVector loopVectorAddition(NumericVector first, NumericVector second) {
    assert (first.length() == second.length());
    NumericVector results(first.length());
    for(unsigned i = 0; i != first.length(); i++)
        results[i] = first[i] + second[i];
    return results;
}

struct VectorAddition : public Worker
{
    const RVector<double> first, second;
    RVector<double> results;
    VectorAddition(const NumericVector one, const NumericVector two, NumericVector three) : first(one), second(two), results(three) {}

    void operator()(std::size_t a1, std::size_t a2) {
        std::transform(first.begin() + a1, first.begin() + a2,
                       second.begin() + a1,
                       results.begin() + a1,
                       [](double i, double j) {return i + j;});
    }
};


// [[Rcpp::export]]
NumericVector parallelVectorAddition(NumericVector first, NumericVector second) {
    assert (first.length() == second.length());
    NumericVector results(first.length());
    VectorAddition myVectorAddition(first, second, results);
    parallelFor(0, first.length(), myVectorAddition);
    return results;
}
/[[Rcpp::depends(RcppParallel)]]
#包括
#包括
#包括
使用名称空间RcppParallel;
使用名称空间Rcpp;
//[[Rcpp::导出]]
NumericVector DirectVector加法(NumericVector第一,NumericVector第二){
断言(first.length()==second.length());
数值向量结果(first.length());
结果=第一+第二;
返回结果;
}
//[[Rcpp::导出]]
NumericVector LoopVector加法(NumericVector第一,NumericVector第二){
断言(first.length()==second.length());
数值向量结果(first.length());
for(无符号i=0;i!=first.length();i++)
结果[i]=第一[i]+第二[i];
返回结果;
}
结构向量添加:公共工作者
{
第一个常数,第二个常数;
评估结果;
向量加法(常数数值向量一,常数数值向量二,数值向量三):第一(一),第二(二),结果(三){
void运算符(){
转换(first.begin()+a1,first.begin()+a2,
第二,begin()+a1,
results.begin()+a1,
[](双i,双j){返回i+j;});
}
};
//[[Rcpp::导出]]
NumericVector并行向量加法(NumericVector第一,NumericVector第二){
断言(first.length()==second.length());
数值向量结果(first.length());
向量添加myVectorAddition(第一,第二,结果);
parallelFor(0,first.length(),myVectorAddition);
返回结果;
}
它似乎可以工作,但不能加快速度(至少在4核机器上不能)

>v1 v2 all(directVectorAddition(v1,v2)=loopVectorAddition(v1,v2))
[1] 真的
>全部(直接矢量加法(v1,v2)=并行矢量加法(v1,v2))
[1] 真的
>结果结果[,1:4]
测试复制相对已过
1 v1+v2 100 0.206 1.000
4平行矢量加法(v1,v2)100 0.993 4.820
2 directVectorAddition(v1,v2)100 1.015 4.927
3环矢量加法(v1,v2)100 1.056 5.126
这能更有效地实施吗

提前多谢了

mce

新手错误:)您将其定义为
Rcpp::NumericVector
,但创建通过序列运算符创建的数据。这将创建整数值,因此您将强制在所有函数上创建一个副本

成功

v1 <- as.double(1:1000000)
v2 <- as.double(1000000:1)
这个例子仍然没有那么令人印象深刻,因为相关的操作“便宜”,而并行方法需要分配内存、将数据复制到工作人员、再次收集等


但好消息是您正确地编写了并行代码。这不是一项小任务。

好的!非常感谢您的快速回复!
v1 <- as.double(1:1000000)
v2 <- as.double(1000000:1)
R> result[,1:4]
                            test replications elapsed relative
4 parallelVectorAddition(v1, v2)          100   0.301    1.000
2   directVectorAddition(v1, v2)          100   0.424    1.409
1                        v1 + v2          100   0.436    1.449
3     loopVectorAddition(v1, v2)          100   0.736    2.445