我想在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;流程,但他们不做任何工作:
我希望这不是重复,但我找不到任何可以提出的搜索字词。
答案 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包。