在 foreach 循环内部使用 foreach 循环并没有什么特别的问题。以下是 doSNOW 循环内的 doMC 循环的示例:
library(doSNOW)
hosts <- c('host-1', 'host-2')
cl <- makeSOCKcluster(hosts)
registerDoSNOW(cl)
r <- foreach(i=1:4, .packages='doMC') %dopar% {
registerDoMC(2)
foreach(j=1:8, .combine='c') %dopar% {
i * j
}
}
stopCluster(cl)
对我来说,将 doMC 用于内部循环似乎很自然,但您可以按照自己的意愿进行操作。您还可以对两个循环使用 doSNOW,但随后您需要在外部 foreach 循环内创建并停止雪簇。
下面是在 doMC 循环中使用 doMC 的示例:
library(doMC)
registerDoMC(2)
r <- foreach(i=1:2, .packages='doMC') %dopar% {
ppid <- Sys.getpid()
registerDoMC(2)
foreach(j=1:2) %dopar% {
c(ppid, Sys.getpid())
}
}
结果表明,尽管只有四个执行内部循环的主体,但 doMC 包总共派生了六个进程:
> r
[[1]]
[[1]][[1]]
[1] 14946 14949
[[1]][[2]]
[1] 14946 14951
[[2]]
[[2]][[1]]
[1] 14947 14948
[[2]][[2]]
[1] 14947 14950
当然,您需要注意不要在单个节点上启动太多进程。我发现这种嵌套有点尴尬,这导致了嵌套运算符的开发。