为什么我的二级期货连续执行?

时间:2018-06-11 12:32:29

标签: r parallel-processing r-future

我正在尝试复制Example中的示例。引用:

  

期货可以嵌套在R中,以便一个未来创造另一套期货   等等。例如,这可能发生在嵌套的for循环[...]

作者使用plan(list(multicore, multicore))(进一步论证和省略tweak)来同时处理两个期货,其中每个期货同时处理四个期货。这应该等于同步处理的8个期货。

但是,当我尝试使用下面的代码重现时,我看到第二级期货是按顺序处理的。我做错了什么?

MCVE

library(future)
library(ggplot2)
plan(list(multiprocess, multiprocess))


# Run for a random amount of time and return start and stop time
startStop <- function(){
  start <- Sys.time()
  x <- runif(1, 1, 3)
  Sys.sleep(x)
  stop <- Sys.time()
  return(data.frame(start = start, stop = stop))
}

nGrp <- 3
nCV <- 4

l <- rep(list(NULL), nGrp)


for(i in seq_along(l)){
  l[[i]] <- future({
    m <- rep(list(NULL), nCV)
    for(j in seq_along(m)){
      m[[j]] <- future(startStop())
    }
    m <- lapply(m, value)
    m <- do.call(rbind, m)
    m
  })
}
l <- lapply(l, value)
d <- do.call(rbind, l)
d$iGrp <- rep(seq_len(nGrp), each = nCV)
d$iCV <- rep(seq_len(nCV), times = nGrp)

d$x <- paste(d$iGrp, d$iCV, sep = "_")
d$iGrp <- as.character(d$iGrp)
ggplot(d, aes(x = x, ymin = start, ymax = stop, color = iGrp)) + geom_linerange() + coord_flip()

topology vignette of the future package

期望

time evolution of futures execution

会话信息

R version 3.4.3 (2017-11-30)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: CentOS Linux 7 (Core)

Matrix products: default
BLAS: /opt/Bio/R/3.4.3/lib64/R/lib/libRblas.so
LAPACK: /opt/Bio/R/3.4.3/lib64/R/lib/libRlapack.so

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
 [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] ggplot2_2.2.1 future_1.8.1 

loaded via a namespace (and not attached):
 [1] Rcpp_0.12.17     devtools_1.13.4  munsell_0.4.3    colorspace_1.3-2
 [5] R6_2.2.2         rlang_0.1.6      httr_1.3.1       plyr_1.8.4      
 [9] globals_0.11.0   tools_3.4.3      parallel_3.4.3   grid_3.4.3      
[13] gtable_0.2.0     git2r_0.21.0     withr_2.1.1      yaml_2.1.16     
[17] lazyeval_0.2.1   digest_0.6.15    tibble_1.4.2     codetools_0.2-15
[21] curl_3.1         memoise_1.1.0    compiler_3.4.3   pillar_1.1.0    
[25] scales_0.5.0     listenv_0.7.0 

2 个答案:

答案 0 :(得分:3)

此处future的作者:这是因为存在针对嵌套并行性的内置保护。如果没有它,您将使用过多的并行进程使计算机过载,这不仅会使其过热而且会降低整体性能。

我已经使用以下部分更新了下一个版本的'Future Topologies'插图:

  

内置防止递归并行性的保护

     

上面我们已经并行处理了未来的外部或内部集合。如果我们想要并行处理两个层怎么办?使用起来很诱人:

plan(list(multiprocess, multiprocess))
     

虽然这没有给出错误,但我们会发现期货的内层将按顺序处理,就像我们使用plan(list(multiprocess, sequential))一样。此行为是由于内置的​​嵌套并行性保护。如果两个层并行运行,每个层使用机器上可用的8个核心,我们将运行8 * 8 = 64个并行进程 - 这肯定会使我们的计算机过载。内部发生的是,对于外层,availableCores()等于八(8),而对于内层,它等于一(1)。

     

现在,我们可以想象我们用两个平行期货处理外层,然后用四个平行期货处理内层。在这种情况下,我们最终将运行最多八个核心(= 2 * 4)。这可以通过在每一层强制固定数量的工人来实现(不推荐):

plan(list(tweak(multiprocess, workers = 2), tweak(multiprocess, workers = 4)))

答案 1 :(得分:1)

如果您希望实现与预期数字类似的并行处理,future.callr是您的选择。 只需使用: library(future.callr) plan(list(callr, callr))