期货可以嵌套在R中,以便一个未来创造另一套期货 等等。例如,这可能发生在嵌套的for循环[...]
中
作者使用plan(list(multicore, multicore))
(进一步论证和省略tweak
)来同时处理两个期货,其中每个期货同时处理四个期货。这应该等于同步处理的8个期货。
但是,当我尝试使用下面的代码重现时,我看到第二级期货是按顺序处理的。我做错了什么?
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
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
答案 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))