Foreach& SNOW在Windows上不起作用

时间:2014-05-14 15:34:21

标签: r parallel-processing

我想在Windows机器上使用foreach循环来在cpu繁重计算中使用多个核心。但是,我无法让流程完成任何工作。

以下是我认为应该起作用的最小例子,但不是:

library(snow)
library(doSNOW)
library(foreach)

cl <- makeSOCKcluster(4)
registerDoSNOW(cl)

pois <- rpois(1e6, 1500) # draw 1500 times from poisson with mean 1500

x <- foreach(i=1:1e6) %dopar% {
  runif(pois[i]) # draw from uniform distribution pois[i] times
}

stopCluster(cl)

SNOW确实创造了4&#34;奴隶&#34;流程,但他们不做任何工作: Task Manager Screenshot

我希望这不是重复,但我找不到任何可以提出的搜索字词。

2 个答案:

答案 0 :(得分:3)

它可能正在工作(至少它在我的Mac上)。但是,对runif的一次调用花费的时间很少,以至于所有时间都用于开销,而子进程在实际任务中花费的CPU功率可以忽略不计。

x <- foreach(i=1:20) %dopar% {
  system.time(runif(pois[i])) 
}
x[[1]]
#user  system elapsed 
#   0       0       0 

如果您有一些无法优化的繁重计算,并行化是有意义的。在你的例子中并非如此。您不需要向runif拨打1e6电话,其中一个就足够了(例如,runif(sum(pois))然后拆分结果)。

PS:总是用较小的例子进行测试。

答案 1 :(得分:2)

虽然这个特殊的例子并不值得并行执行,但值得注意的是,因为它使用了doSNOW,所以整个pois向量会自动导出到所有工作者,即使每个工人只需要一小部分。但是,您可以通过迭代pois本身来避免将任何数据自动导出到工作人员:

x <- foreach(p=pois) %dopar% {
  runif(p)
}

现在pois的元素被发送给任务中的工作者,因此每个工作者只接收执行其任务所需的数据。使用doMC时,此技术并不重要,因为doMC工作人员可以免费获得pois

您还可以通过使用迭代器函数(例如&#34; isplitVector&#34;)在较大的块中处理pois来极大地提高性能。来自itertools包。