我需要计算矢量和大矩阵(> 1000000行)之间的余弦距离相似度。代码如下。它工作正常,但我没有看到我的8核机器的100%利用率(没有其他任何东西在它上运行)和整体速度超过线性版本的“余弦(vecA,matB)”是非常低的。
如果没有8次使用8个内核,是否有一个技巧我缺少加速至少5-6次?谢谢!
我查看了其他R并行链接,但找不到可以解释我做错的答案。
library(parallel)
library(lsa)
cosine.par <- function(cl, vecA, matB){
Blist <- lapply(c(1:ncol(matB)), function(ii) as.vector(matB[,ii,drop=FALSE]))
#print("Parallel Call")
ans <- clusterApply(cl, Blist, cosine, vecA)
do.call(rbind, ans)
}
k=500
vecA=c(1:k)
matB=matrix(rep(c(1:k),1000000), ncol=1000000)
nc <- detectCores()
cl <- makeCluster(rep("localhost", nc))
print(paste(format(Sys.time(),
"%a %b %d %X %Y %Z")))
cosine.par(cl, vecA, matB)
print(paste(format(Sys.time(),
"%a %b %d %X %Y %Z")))
stopCluster(cl)
答案 0 :(得分:1)
我认为问题在于你执行了一百万个小任务,效率极低。在这种情况下,您可以使用parApply
功能:
cosine.par <- function(cl, vecA, matB) {
r <- parApply(cl, matB, 2, cosine, vecA)
dim(r) <- c(length(r), 1)
r
}
这对我来说比原始代码运行得快得多,但是当矩阵对于你的机器来说太大时,你仍然会遇到问题。
由于您使用的是Mac,因此您也可以尝试使用mclapply
:
cosine.mc <- function(nc, vecA, matB) {
r <- unlist(mclapply(1:nc, function(i) {
n <- ceiling(ncol(matB) / nc)
j <- (n * (i - 1)) + 1
k <- min(n * i, ncol(matB))
apply(matB[,seq(j, k), drop=FALSE], 2, cosine, vecA)
}, mc.cores=nc))
dim(r) <- c(length(r), 1)
r
}
虽然这非常有效,但在使用mclapply
的大型矩阵上运行时遇到以下错误。
Error in mcfork() :
unable to fork, possible reason: Cannot allocate memory
如果出现此错误,您将需要使用更少的内存,使用更少的工作人员或为计算机添加更多内存。