2015-07-19 33 views
2

我需要计算向量和大矩阵(> 1000000行)之间的余弦距离相似度。代码如下。它工作正常,但我没有看到我的8核心机器(没有别的运行在其上)的100%利用率,并且整体加速超过线性版本的“余弦(vecA,matB)”是相当低的。并行余弦距离在R中使用clusterapply

有没有一招我缺少加速至少5-6倍,如果不是8次使用8核?谢谢!

我已经看过其他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

你观察到了哪些CPU使用情况?如果这些进程在计算时间上有所不同,那么您可能需要尝试执行负载平衡的'clusterApplyLB'。我还发现,在一些使用英特尔CPU的机器上,有必要关闭超线程以实现所需的行为。 – SimonG

+0

我有8核心Mac运行2.4GZ英特尔。最高命令显示8R过程每个CPU的25-30%cpu,整体总利用率也是30%。我期望每个内核的90%接近750%的总数,这在并行应用程序中不是非典型的,例如这个 –

+1

内存怎么样?如果单个CPU负载仅为25%,则可能是“余弦”仅仅是内存而不是CPU密集型。就像我说的,如果你真的需要计算能力,那么尝试禁用HT。然而,谨慎地说,让所有内核100%忙碌可能会使系统无法运行,直到计算完成(无HT)。 – SimonG

回答

1

我认为问题是,你执行一百万微小的任务,它是非常低效的。在这种情况下,你可以使用parApply功能:

cosine.par <- function(cl, vecA, matB) { 
    r <- parApply(cl, matB, 2, cosine, vecA) 
    dim(r) <- c(length(r), 1) 
    r 
} 

这快得多运行,我比你原来的代码,但你还是会遇到问题时,矩阵变得太大,为您的机器。与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 
} 

虽然这是很有效的,我遇到了以下错误:

由于您使用的是Mac,你也可以尝试使用mclapply

Error in mcfork() : 
    unable to fork, possible reason: Cannot allocate memory 

如果你得到这个错误,你将不得不使用更少的内存,使用更少的工人,或添加更多的内存到您的计算机。

+0

非常好!什么是最后的dim(r)< - c(length(r),1)for? –

+0

@WDTWDT它是可选的,但它以与您的示例相同的方式设置“dim”属性。如果将它排除在外,结果将是一个矢量,而不是具有一列的矩阵。 –

+0

虽然parApply运行良好,但我观察到执行过程中每个8 R进程的CPU使用率,只有两个进程达到90%的CPU级别,而其他进程只能保持在0%。如何充分利用所有8核? –