Parallel processing OpenMP和(Rcpp)特征值
我想知道如何编写代码,有时使用内置在Egeng库中的OpenMP并行化,而有时使用我指定的并行化。希望下面的代码片段能够为我的问题提供背景信息。 我在我的库的设计阶段问这个问题(很抱歉,我没有一个工作/中断的代码示例)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并行 对于
\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;i A最简单的方法可能是在运行时禁用/启用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