1

当我试图了解R包的文档时parallel,我在阅读包文档第 8 页上的一些代码行时遇到了这个问题。我已经复制了下面的代码。请注意,mc仅等于2

# mc = 2
cl <- makeCluster(mc)
cd4.rg <- function(data, mle) MASS::mvrnorm(nrow(data), mle$m, mle$v)
cd4.mle <- list(m = colMeans(cd4), v = var(cd4))
clusterExport(cl, c("cd4.rg", "cd4.mle"))
junk <- clusterEvalQ(cl, library(boot)) # discard result
clusterSetRNGStream(cl, 123)
res <- clusterEvalQ(cl, boot(cd4, corr, R = 500,
+                   sim = "parametric", ran.gen = cd4.rg, mle = cd4.mle))
library(boot) # needed for c() method on master
cd4.boot <- do.call(c, res)
boot.ci(cd4.boot, type = c("norm", "basic", "perc"),
+                   conf = 0.9, h = atanh, hinv = tanh)
stopCluster(cl)

在第 5 行,该命令library(boot)已在 上进行评估cl,但在第 8 行library(boot)再次运行,作者说它是c()master 上的方法所必需的。

我原来的理解是:makeCluster(mc)创建两个worker进程,master进程就是其中之一。现在看起来,由创建的每个工人makeCluster(mc)都与主进程不同。因此library(boot)必须在主进程上运行。我说得对吗?

如果我有一个 8 核 CPU,这是否意味着创建超过 7 个(>7)工作进程完全没有用?谢谢你。

4

1 回答 1

0

在我的系统上,可以看到 makeCluster(2) 创建了 2 个额外的R 进程(我在 Windows 上,可以在资源监视器中看到它们)。因此,“工人”似乎不同于“主”流程,并且是“主”流程的补充。

至于库,一个快速检查的方法是向每个工作人员询问其loadedNamespaces(). 下面的脚本显示了这个foreach包被加载到两个工人上的例子,loadedNamespaces()之前和之后是工人和主人。

由于只有工作进程用于执行表达式 by clusterEvalQ,因此将工作人员的数量增加到最多 8 个从表面上看似乎是明智的。实际性能将取决于其他因素,例如 8 核系统上可用的逻辑核心数量、每个核心在处理中所做的事情以及当时系统上发生的其他事情,......

成绩单:

library(parallel)
cl <- makeCluster(2)
loadedNamespaces() # get loaded namespaces on master
# [1] "base"      "datasets"  "graphics"  "grDevices" "methods"   "parallel"  "stats"     "utils"
clusterEvalQ(cl, loadedNamespaces()) # get loaded namespaces on workers
# [[1]]
# [1] "base"      "datasets"  "graphics"  "grDevices" "methods"   "parallel"  "stats"     "utils"    
# 
# [[2]]
# [1] "base"      "datasets"  "graphics"  "grDevices" "methods"   "parallel"  "stats"     "utils"    
# 
invisible( clusterEvalQ(cl, library(foreach)) ) # load foreach on workers
loadedNamespaces() # check master
# [1] "base"      "datasets"  "graphics"  "grDevices" "methods"   "parallel"  "stats"     "utils"
clusterEvalQ(cl, loadedNamespaces()) # check workers
# [[1]]
#  [1] "base"      "codetools" "datasets"  "foreach"   "graphics"  "grDevices" "iterators" "methods"   "parallel"  "stats"     "utils"    
# 
# [[2]]
#  [1] "base"      "codetools" "datasets"  "foreach"   "graphics"  "grDevices" "iterators" "methods"   "parallel"  "stats"     "utils"    
# 
library(foreach) # load foreach on master
# foreach: simple, scalable parallel programming from Revolution Analytics
# Use Revolution R for scalability, fault tolerance and more.
# http://www.revolutionanalytics.com
loadedNamespaces() # check again
# [1] "base"      "codetools" "datasets"  "foreach"   "graphics"  "grDevices" "iterators" "methods"   "parallel"  "stats"     "utils"    
stopCluster(cl) # tidy up
于 2015-11-20T11:42:38.113 回答