每个%的百分比比循环慢 [英] foreach %dopar% slower than for loop

查看:104
本文介绍了每个%的百分比比循环慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么 foreach()%dopar%慢于 $ C>。一些小小的例子:

$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ b $ library $ $ b registerDoParallel(cores = detectCores())

I < - 10 ^ 3L

for.loop < - function(I){
out< ; - 双(I)
(我在seq_len(I))
出[i] < - sqrt(i)

}

foreach.do< - function(I){
out< - foreach(i = seq_len(I),.combine = c)%do%
sqrt(i)
(i = seq_len(I),.combine = c)%dopar%(%)


foreach.dopar<
sqrt(i)

}

相同(for.loop(I),foreach.do(I),foreach.dopar(I))
## [1] TRUE
library(rbenchmark)
基准(for.loop(I),foreach.do(I),foreach.dopar(I))
## (I)100 0.696 1.000 0.690 0.000 0.0 0.000
## 2 foreach.do(I)相对于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 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版本3.0.0(2013 -04-03)
## Platform:x86_64-unknown-linux-gnu(64-bit)
##
## locale:
## [1] LC_CTYPE = LC_COLLATE = ru_RU.UTF-8 LC_MONETARY = ru_RU.UTF-8 LC_MESSAGES = ru_RU.UTF-8
#RU_RU.UTF-8 LC_NUMERIC = C LC_TIME = ru_RU.UTF-8
## [4] #[7] LC_PAPER = C LC_NAME = C LC_ADDRESS = C
## [10] LC_TELEPHONE = C LC_MEASUREMENT = ru_RU.UTF-8 LC_IDENTIFICATION = C
##
##附加的基本软件包:
## [1] parallel stats graphics grDevices utils datasets methods base
##
##其他附加软件包:
## [1] doMC_1.3.0 rbenchmark_1.0.0 doParallel_1 .0.1 iterators_1.0.6 foreach_1.4.0 plyr_1.8
##
##通过命名空间(而不是附加)加载:
## [1] codetools_0.2-8 compiler_3.0.0 tools_3.0.0

getDoParWorkers()
## [1] 4


解决方案

具体提到并用示例说明,确实有时候这样做会比较慢,因为必须将doParallel包中的单独并行进程的结果合并起来。

参考: http:/ /cran.r-project.org/web/packages/doParallel/vignettes/gettingstartedParallel.pdf



第3页:


对于小任务,调度任务和返回
结果的开销可能大于执行任务本身的时间,
导致性能差。


我用这个例子发现,在某些情况下,使用这个包会导致执行所需时间的50%该代码。


Why foreach() with %dopar% slower than for. Some litle exmaple:

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

Some addition info:

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

解决方案

It is specifically mentioned and illustrated with examples that indeed sometimes it's slower to set this up, because of having to combine the results from the separate parallel processes in the package doParallel.

Reference: http://cran.r-project.org/web/packages/doParallel/vignettes/gettingstartedParallel.pdf

Page 3:

With small tasks, the overhead of scheduling the task and returning the result can be greater than the time to execute the task itself, resulting in poor performance.

I used the example to find out that in some case, using the package resulted in 50% the time needed to execute the code.

这篇关于每个%的百分比比循环慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆