Ответ 1
Для задачи, подобной вашей (и, если на то пошло, для любой задачи, для которой мне когда-либо понадобился parallel) parLapplyLB
, на самом деле не является правильным инструментом для задания. Чтобы понять, почему нет, посмотрите, как он реализован:
parLapplyLB
# function (cl = NULL, X, fun, ...)
# {
# cl <- defaultCluster(cl)
# do.call(c, clusterApplyLB(cl, x = splitList(X, length(cl)),
# fun = lapply, fun, ...), quote = TRUE)
# }
# <bytecode: 0x000000000f20a7e8>
# <environment: namespace:parallel>
## Have a look at what `splitList()` does:
parallel:::splitList(1:4, 2)
# [[1]]
# [1] 1 2
#
# [[2]]
# [1] 3 4
Проблема заключается в том, что он сначала разбивает свой список заданий на подсписные числа равного размера, а затем распределяет между узлами, каждый из которых запускает lapply()
в своем заданном подсписке. Таким образом, ваш первый node запускает задания на первом и втором входах, а второй node выполняет задания с использованием третьего и четвертого входов.
Вместо этого используйте более универсальный clusterApplyLB()
, который работает так, как вы надеетесь:
system.time(
parallel::clusterApplyLB(cl, 1:4, function(y) {
if (y == 1) {
Sys.sleep(3)
} else {
Sys.sleep(0.5)
}}))
# user system elapsed
# 0.00 0.00 3.09