Как понять мастер и рабочие процессы ---R пакета "параллель"?
Как я пытался понять документацию 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()
метод на мастера.
Мое первоначальное понимание таково: makeCluster(mc)
создает два рабочих процесса, и главный процесс является одним из них. Теперь похоже, что каждый из рабочих, созданных makeCluster(mc)
отличается от основного процесса. И поэтому library(boot)
должен быть запущен на главном процессе. Я прав в этом?
Если у меня 8-ядерный процессор, значит ли это, что создание более семи (> 7) рабочих процессов совершенно бесполезно? Спасибо.
1 ответ
В моей системе makeCluster(2) может создавать 2 дополнительных процесса R (я в Windows и вижу их в Resource Monitor). Таким образом, "рабочие", похоже, отличаются от "основного" процесса и дополняют его.
Что касается библиотек, быстрый способ проверить это - попросить каждого работника loadedNamespaces()
, Ниже транскрипция показывает это на примере foreach
пакет загружается на двух рабочих, с loadedNamespaces()
для рабочих и мастера до и после.
Поскольку только рабочие процессы используются для выполнения выражения 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