Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parallel processing OpenMP和(Rcpp)特征值_Parallel Processing_Openmp_Eigen - Fatal编程技术网

Parallel processing OpenMP和(Rcpp)特征值

Parallel processing OpenMP和(Rcpp)特征值,parallel-processing,openmp,eigen,Parallel Processing,Openmp,Eigen,我想知道如何编写代码,有时使用内置在Egeng库中的OpenMP并行化,而有时使用我指定的并行化。希望下面的代码片段能够为我的问题提供背景信息。 我在我的库的设计阶段问这个问题(很抱歉,我没有一个工作/中断的代码示例) \ifdef\u OPENMP #包括 #恩迪夫 #包括 void fxn(…,int ncores=-1){ 如果(ncores>0)omp_集合_num_线程(ncores); /* *矩阵积编码 *我想用艾根的 *OpenMP并行化 */ #pragma-omp并行 对于

我想知道如何编写代码,有时使用内置在Egeng库中的OpenMP并行化,而有时使用我指定的并行化。希望下面的代码片段能够为我的问题提供背景信息。 我在我的库的设计阶段问这个问题(很抱歉,我没有一个工作/中断的代码示例)

\ifdef\u OPENMP
#包括
#恩迪夫
#包括
void fxn(…,int ncores=-1){
如果(ncores>0)omp_集合_num_线程(ncores);
/*
*矩阵积编码
*我想用艾根的
*OpenMP并行化
*/ 
#pragma-omp并行
对于(int i=0;i
控制Egen自身与OpenMP的并行化和我自己的并行化之间的平衡的最佳实践是什么

更新: 我写了一个简单的例子并测试了ggael的建议。简言之,我怀疑它是否解决了我提出的问题(或者我做错了其他事情——如果是后者,请道歉)。请注意,对于for循环的显式并行化,运行时没有任何变化(甚至不是一个慢循环)

#ifdef _OPENMP
  #include <omp.h>
#endif 
#include <RcppEigen.h>

using namespace Rcpp;
// [[Rcpp::plugins(openmp)]]

// [[Rcpp::export]]
Eigen::MatrixXd testing(Eigen::MatrixXd A, Eigen::MatrixXd B, int n_threads=1){
  Eigen::setNbThreads(n_threads);
  Eigen::MatrixXd C = A*B;
  Eigen::setNbThreads(1);
  for (int i=0; i < A.cols(); i++){
    A.col(i).array() = A.col(i).array()*B.col(i).array(); 
  }
  return A;
}

// [[Rcpp::export]]
Eigen::MatrixXd testing_omp(Eigen::MatrixXd A, Eigen::MatrixXd B, int n_threads=1){
  Eigen::setNbThreads(n_threads);
  Eigen::MatrixXd C = A*B;
  Eigen::setNbThreads(1);
  #pragma omp parallel for num_threads(n_threads)
  for (int i=0; i < A.cols(); i++){
    A.col(i).array() = A.col(i).array()*B.col(i).array(); 
  }
  return A;
}


/*** R
A <- matrix(rnorm(1000*1000), 1000, 1000)
B <- matrix(rnorm(1000*1000), 1000, 1000)
microbenchmark::microbenchmark(testing(A,B, n_threads=1),
                               testing_omp(A,B, n_threads=1),
                               testing(A,B, n_threads=8), 
                               testing_omp(A,B, n_threads=8), 
                               times=10)
*/

Unit: milliseconds
                             expr       min        lq      mean    median        uq       max neval cld
     testing(A, B, n_threads = 1) 169.74272 183.94500 212.83868 218.15756 236.97049 264.52183    10   b
 testing_omp(A, B, n_threads = 1) 166.53132 178.48162 210.54195 227.65258 234.16727 238.03961    10   b
     testing(A, B, n_threads = 8)  56.03258  61.16001  65.15763  62.67563  67.37089  83.43565    10  a 
 testing_omp(A, B, n_threads = 8)  54.18672  57.78558  73.70466  65.36586  67.24229 167.90310    10  a 
\ifdef\u OPENMP
#包括
#恩迪夫
#包括
使用名称空间Rcpp;
//[[Rcpp::插件(openmp)]]
//[[Rcpp::导出]]
特征::矩阵xD测试(特征::矩阵xD A,特征::矩阵xD B,整数n_线程=1){
特征::setNbThreads(n_线程);
本征::矩阵xDC=A*B;
特征::setNbThreads(1);
for(int i=0;iA最简单的方法可能是在运行时禁用/启用Eigen的多线程:

Eigen::setNbThreads(1); // single thread mode
#pragma omp parallel for
for (int i=0; i < iter; i++){ 
  // Code I would like to parallelize "myself"
  // even though it involves matrix products
}
Eigen::setNbThreads(0); // restore default
Eigen::setNbThreads(1);//单线程模式
#pragma-omp并行
对于(int i=0;i
真的不是Rcpp问题。这是你和艾根之间的问题。也许删除
Rcpp
标签?很好的观点。但是我似乎无法做到。抱歉!奇怪,你应该能够在你的帖子中包含标签。不管怎样,我现在删除了标签…正如拉尔夫强调的,你可以随时编辑自己的帖子。而且,你的循环不是执行任何矩阵积,但系数积无论如何都不能与Eigen并行。因此,禁用Eigen对此循环的多线程处理与否不会有任何区别。顺便说一句,for循环也可以直接写成
A.array()*=B.array();
我用这个建议更新了我的问题。简言之,我认为这不能解决问题。如果我犯了错误或没有正确解释你的答案,我深表歉意。
Eigen::setNbThreads(1); // single thread mode
#pragma omp parallel for
for (int i=0; i < iter; i++){ 
  // Code I would like to parallelize "myself"
  // even though it involves matrix products
}
Eigen::setNbThreads(0); // restore default