mclapply
位于 parallel
包(package)。 说明
mclapply
是 lapply
的并行化版本,它返回与 X
相同长度的列表,其中每个元素是将 FUN
应用于 X
的相应元素的结果。
它依赖于分叉,因此在 Windows 上不可用,除非 mc.cores = 1
。
mcmapply
是 mapply
的并行化版本,mcMap
对应于 Map
。
用法
mclapply(X, FUN, ...,
mc.preschedule = TRUE, mc.set.seed = TRUE,
mc.silent = FALSE, mc.cores = getOption("mc.cores", 2L),
mc.cleanup = TRUE, mc.allow.recursive = TRUE, affinity.list = NULL)
mcmapply(FUN, ...,
MoreArgs = NULL, SIMPLIFY = TRUE, USE.NAMES = TRUE,
mc.preschedule = TRUE, mc.set.seed = TRUE,
mc.silent = FALSE, mc.cores = getOption("mc.cores", 2L),
mc.cleanup = TRUE, affinity.list = NULL)
mcMap(f, ...)
参数
X |
向量(原子或列表)或表达式向量。其他对象(包括分类对象)将被 |
FUN |
与 |
f |
与 |
... |
对于 |
MoreArgs, SIMPLIFY, USE.NAMES |
请参阅 |
mc.preschedule |
如果设置为 |
mc.set.seed |
请参阅 |
mc.silent |
如果设置为 |
mc.cores |
要使用的核心数量,即最多同时运行多少个子进程。该选项是从环境变量初始化的MC_CORES如果设置。必须至少为一,并且并行化至少需要两个核心。 |
mc.cleanup |
如果设置为 |
mc.allow.recursive |
除非 true,否则在子进程中调用 |
affinity.list |
一个向量(原子或列表),包含 |
细节
mclapply
是 lapply
的并行版本,提供 mc.cores > 1
:对于 mc.cores == 1
(并且 affinity.list
是 NULL
),它只需调用 lapply
。
默认情况下 ( mc.preschedule = TRUE
) 输入 X
被分成与核心数量一样多的部分(当前值按顺序分布在核心上,即第一个值到核心 1,第二个值到核心 2,...(核心+ 1)-th 值到核心 1 等),然后将一个进程分叉到每个核心并收集结果。
如果不进行预先调度,则会为 X
的每个值分叉一个单独的作业。为了确保同时运行的作业数量不超过 mc.cores
,一旦该数量已分叉,主进程就会在下一个分叉之前等待子进程完成。
由于执行的并行性质,随机数不像使用 lapply
时那样是连续的(在随机数序列中)。它们对于每个分叉进程都是连续的,但并非所有作业作为一个整体都是连续的。请参阅 mcparallel
或包的插图,了解使用 mc.preschedule = TRUE
重现结果的方法。
注意:文件说明符(和进程)的数量通常受到操作系统的限制,因此您可能会在使用超过 100 个核心左右时遇到问题(请参阅 ulimit -n
或操作系统文档中的类似内容),除非您提高允许的限制打开文件说明符(fork 将失败并出现错误 "unable to create a pipe"
)。
之前R3.4.0 和 32 位平台上,base serialize每个分叉进程的 d 结果仅限于 字节。 (通过序列化返回非常大的结果效率低下,应该避免。)
affinity.list
可用于在特定 CPU 上运行 X
的元素。如果 X
的元素完成时间差异很大或者硬件架构是异构的,这可能会很有帮助。它还可以开发调度策略来优化并行作业的整体运行时间。如果设置了 affinity.list
,则 mc.core
参数将替换为关联掩码中使用的 CPU ID 数。
值
对于 mclapply
,与 X
长度相同并由 X
命名的列表。
对于 mcmapply
、列表、向量或数组:请参阅 mapply
。
对于 mcMap
,一个列表。
每个分叉进程都在内部运行其作业try(..., silent = TRUE)
因此,如果发生错误,它们将被存储为类"try-error"
返回值中包含对象,并会给出警告。请注意,这项工作通常会涉及多个值X
因此"try-error"
将为失败所涉及的所有值返回对象,即使并非所有值都失败。如果任何分叉进程被终止或由于任何原因未能提供结果,则失败涉及的值将是NULL
。为了允许检测此类错误,FUN
不应该返回NULL
。作为R4.0、返回值mcmapply
当需要包含时始终是一个列表"try-error"
对象(SIMPLIFY
被覆盖为FALSE
)。
警告
强烈建议不要在 GUI 或嵌入式环境中使用这些函数,因为它会导致多个进程共享同一 GUI,这可能会导致混乱(甚至可能崩溃)。子进程永远不应该使用屏幕上的图形设备。
已采取一些预防措施使其可在 macOS 上的 R.app
中使用,但第三方 front-ends 的用户应查阅其文档。
请注意,tcltk
算作用于这些目的的 GUI,因为 Tcl
运行事件循环。该事件循环在子进程中被禁止,但 Tk 图形连接仍然可能存在问题。
强烈建议不要将这些函数与多线程库或包一起使用(有关更多详细信息,请参阅mcfork
)。如果有疑问,使用非 FORK 集群会更安全(请参阅makeCluster
、clusterApply
)。
例子
simplify2array(mclapply(rep(4, 5), rnorm))
# use the same random numbers for all values
set.seed(1)
simplify2array(mclapply(rep(4, 5), rnorm, mc.preschedule = FALSE,
mc.set.seed = FALSE))
## Contrast this with the examples for clusterCall
library(boot)
cd4.rg <- function(data, mle) MASS::mvrnorm(nrow(data), mle$m, mle$v)
cd4.mle <- list(m = colMeans(cd4), v = var(cd4))
mc <- getOption("mc.cores", 2)
run1 <- function(...) boot(cd4, corr, R = 500, sim = "parametric",
ran.gen = cd4.rg, mle = cd4.mle)
## To make this reproducible:
set.seed(123, "L'Ecuyer")
res <- mclapply(seq_len(mc), run1)
cd4.boot <- do.call(c, res)
boot.ci(cd4.boot, type = c("norm", "basic", "perc"),
conf = 0.9, h = atanh, hinv = tanh)
## Usage of the affinity.list parameter
A <- runif(2500000,0,100)
B <- runif(2500000,0,100)
C <- runif(5000000,0,100)
first <- function(i) head(sort(i), n = 1)
# Restict all elements of X to run on CPU 1 and 2
affL <- list(c(1,2), c(1,2), c(1,2))
mclapply(list(A, A, A), first, mc.preschedule = FALSE, affinity.list = affL)
# Completion times are assumed to have a high variance
# To optimize the overall execution time elements of X are scheduled to suitable CPUs
# Assuming that the runtime for C is as long as the runtime of A plus B
# mapping: A to 1 , B to 1, C to 2
X <- list(A, B, C)
affL <- c(1, 1, 2)
mclapply(X, first, mc.preschedule = FALSE, affinity.list = affL)
作者
Simon Urbanek and R Core.
The affinity.list
feature by Helena Kotthaus and Andreas Lang,
TU Dortmund.
Derived from the multicore
package formerly on CRAN.
也可以看看
mcparallel
、pvec
、parLapply
、clusterMap
。
simplify2array
用于类似 sapply
的结果。
相关用法
- R mcparallel 在单独的进程中异步计算 R 表达式
- R mcfork 分叉当前 R 进程的副本
- R mcaffinity 获取或设置当前进程的CPU亲和性掩码
- R makeCluster 创建并行套接字集群
- R pvec 使用 Forking 并行化向量映射函数
- R children 用于管理分叉进程的低级函数
- R clusterApply 使用集群应用操作
- R RNGstreams Pierre L'Ecuyer 的 RngStreams 的实施
- R detectCores 检测CPU核心数
- R splitIndices 划分任务在集群中分布
- R SparkR partitionBy用法及代码示例
- R purrr accumulate 累积向量缩减的中间结果
- R purrr imap 将函数应用于向量的每个元素及其索引
- R purrr list_transpose 转置列表
- R purrr as_vector 将列表强制转换为向量
- R purrr map_if 有条件地将函数应用于向量的每个元素
- R purrr map2 映射两个输入
- R purrr map_depth 在给定深度映射/修改元素
- R SparkR printSchema用法及代码示例
- R purrr list_simplify 将列表简化为原子或 S3 向量
- R purrr rerun 多次重新运行表达式
注:本文由纯净天空筛选整理自R-devel大神的英文原创作品 Parallel Versions of lapply and mapply using Forking。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。