我将R的默认BLAS更改为英特尔MKL并获得足够的速度提升。在我的电脑上,MKL使用4个线程。现在我尝试将我的代码与R中的snow
并行。为了避免两级并行计算之间的冲突,我使用setMKLthreads(1)
仅使用一个核来限制MKL。但是当我运行我的代码时,通过检查Windows任务管理器,所有CPU都参与其中。
#If I run some test example, like
setMKLthreads(1)
set.seed (1)
m <- 10000
n <- 5000
A <- matrix (runif (m*n),m,n)
system.time (B <- crossprod(A))
setMKLthreads(4)
system.time (B <- crossprod(A))
setMKLthreads(2)
system.time (B <- crossprod(A))
更多内核运行速度更快,Windows任务管理器正确反映了所涉及的内核数量。
但为什么setMKLthreads
在我的情况下不起作用?我开始怀疑它是否与我使用Rcpp / RcppArmadillo构建的包有关。我想知道setMKLthreads
是否可以控制C ++级代码?由于任务管理器仍然给我完整的CPU使用率。然后我在设置setMKLthreads(1)
后尝试重新编译我的包,但它也没有用。
如果我的猜测是正确的,我如何更改C ++级别MKL以限制为1个核心?
我在这里添加一个小例子:首先是C ++代码:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::mat cross_cpp(arma::mat A, arma::mat B){
arma::mat C=A*A.t();
return(C);
}
// [[Rcpp::export]]
arma::mat cholesky_cpp(arma::mat A){
arma::mat C=arma::chol(A);
return(C);
}
在R中:我生成了一个带有6000行的正定矩阵,并进行了cholesky分解。虽然对于这个例子,没有时间差异。但我的观点是,如果你可以监控CPU,你会发现无论我为MKL设置多少个核心,它都会一直提升到最大值。在我的例子中,我有4个物理内核和8个逻辑内核,在这两种情况下CPU使用率提高到50%。我期待的是,当我将其限制为1个内核时,最大CPU使用率将为12.5%。
library(clusterGeneration)
B = genPositiveDefMat(dim = 6000)
setMKLthreads(1)
getMKLthreads()
time1 = Sys.time()
C <- cholesky_cpp(B$Sigma)
time2 = Sys.time()
time2-time1
setMKLthreads(4)
getMKLthreads()
time1 = Sys.time()
C <- cholesky_cpp(B$Sigma)
time2 = Sys.time()
time2-time1