foreach %dopar% медленнее, чем для цикла
Зачем foreach()
с %dopar%
медленнее чем for
, Некоторый маленький пример:
library(parallel)
library(foreach)
library(doParallel)
registerDoParallel(cores = detectCores())
I <- 10^3L
for.loop <- function(I) {
out <- double(I)
for (i in seq_len(I))
out[i] <- sqrt(i)
out
}
foreach.do <- function(I) {
out <- foreach(i = seq_len(I), .combine=c) %do%
sqrt(i)
out
}
foreach.dopar <- function(I) {
out <- foreach(i = seq_len(I), .combine=c) %dopar%
sqrt(i)
out
}
identical(for.loop(I), foreach.do(I), foreach.dopar(I))
## [1] TRUE
library(rbenchmark)
benchmark(for.loop(I), foreach.do(I), foreach.dopar(I))
## test replications elapsed relative user.self sys.self user.child sys.child
## 1 for.loop(I) 100 0.696 1.000 0.690 0.000 0.0 0.000
## 2 foreach.do(I) 100 121.096 173.989 119.463 0.056 0.0 0.000
## 3 foreach.dopar(I) 100 120.297 172.841 111.214 6.400 3.5 6.734
Некоторая дополнительная информация:
sessionInfo()
## R version 3.0.0 (2013-04-03)
## Platform: x86_64-unknown-linux-gnu (64-bit)
##
## locale:
## [1] LC_CTYPE=ru_RU.UTF-8 LC_NUMERIC=C LC_TIME=ru_RU.UTF-8
## [4] LC_COLLATE=ru_RU.UTF-8 LC_MONETARY=ru_RU.UTF-8 LC_MESSAGES=ru_RU.UTF-8
## [7] LC_PAPER=C LC_NAME=C LC_ADDRESS=C
## [10] LC_TELEPHONE=C LC_MEASUREMENT=ru_RU.UTF-8 LC_IDENTIFICATION=C
##
## attached base packages:
## [1] parallel stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] doMC_1.3.0 rbenchmark_1.0.0 doParallel_1.0.1 iterators_1.0.6 foreach_1.4.0 plyr_1.8
##
## loaded via a namespace (and not attached):
## [1] codetools_0.2-8 compiler_3.0.0 tools_3.0.0
getDoParWorkers()
## [1] 4
1 ответ
Решение
Это специально упомянуто и проиллюстрировано примерами, которые действительно иногда медленнее настраивают, потому что приходится комбинировать результаты отдельных параллельных процессов в пакете doParallel.
Ссылка: http://cran.r-project.org/web/packages/doParallel/vignettes/gettingstartedParallel.pdf
Страница 3:
Для небольших задач накладные расходы по планированию задачи и возвращению результата могут быть больше, чем время выполнения самой задачи, что приводит к снижению производительности.
Я использовал пример, чтобы выяснить, что в некоторых случаях использование пакета приводит к 50% времени, необходимому для выполнения кода.