在R中使用clusterapply的并行余弦距离

时间:2015-07-19 19:34:51

标签: r matrix parallel-processing

我需要计算矢量和大矩阵(> 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)

1 个答案:

答案 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

如果出现此错误,您将需要使用更少的内存,使用更少的工作人员或为计算机添加更多内存。