如何正确使用doSMP和foreach包?

时间:2011-03-16 12:42:39

标签: r multicore

我正在尝试使用doSMP package为foreach包提供并行后端。

你能指出我做错了什么吗?实际上,以这种方式使用foreach会大大增加计算时间......

#------register doSMP to be used with foreach------
library(doSMP)
w <- startWorkers(4)
registerDoSMP(w)
#--------------------------------------------------

#------A simple function------
sim <- function(a, b)
{
    return(10 * a + b)
}
avec <- 1:200
bvec <- 1:400
#-----------------------------

#------The naive method------
ptime <- system.time({
mat <- matrix(NA, nrow=length(avec), ncol=length(bvec))
for(i in 1:length(avec))
{
    for(j in 1:length(bvec))
    {
         mat[i, j] <- sim(avec[i], bvec[j])
    }
}
})[3]
ptime

elapsed 
   0.36
#----------------------------

#------Using foreach------
ptime <- system.time({
mat2 <- foreach(b=bvec, .combine="cbind") %:%
         foreach(a=avec, .combine="c") %dopar%
     {
            sim(a, b)
    }
})[3]
ptime

elapsed 
  86.98
#-------------------------

修改

That question与此非常相似,已从stats.stackexchange迁移。

2 个答案:

答案 0 :(得分:4)

我个人不喜欢doSMP包,因为它经常崩溃我的R.它是为REvolution构建而开发的,并且无法在我的机器上顺利运行。例如,上面的代码,未经修改,只会崩溃我的R.

接下来,尝试在循环函数中使用并行函数似乎很奇怪。在外循环中进行并行化更为逻辑。嵌套并行计算中涉及的通信导致计算时间的急剧增加。你没有获得任何东西,因为你的sim功能非常快。实际上,保持内部循环序列化更有意义,因为在这种情况下,一个内核上的计算时间会比通信中的开销大。

使用snowfall-package并使用apply for循环而不是for循环的插图。这也很天真,因为矢量化有很多可以获胜(见下文)。

library(snowfall)
sfInit(parallel=T,cpus=2)
#same avec, bvec, sim

system.time({
    out <- sapply(avec,function(i) {
      sapply(bvec,function(j){
        sim(i,j)
      })
    })
})[3]
elapsed 
   0.33 

sfExport("avec","bvec","sim")
system.time({
    out <- sfSapply(avec,function(i) { # this one is parallel
      sapply(bvec,function(j){ # this one is not, no sense in doing so
        sim(i,j)
      })
    })
})[3]
elapsed 
   0.17 

两个矩阵是相同的,除了由于结构的维度名称:

> all.equal(out1,out2)
[1] "Attributes: < Length mismatch: comparison on first 1 components >"

正确的R方式是:

system.time(
  out3 <- outer(avec*10,bvec,"+")
)[3]
elapsed 
   0.01 

明显更快,并创建一个相同的(虽然转置)矩阵:

> all.equal(out1,t(out3))
[1] TRUE

(作为参考,你的双重for循环在我的系统上运行0.73经过时间......)

答案 1 :(得分:0)

Joris Meys给了我一个很好的答案,here也适用于那种情况。对不起,“双帖”