当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


R mclapply 使用 Forking 的 lapply 和 mapply 并行版本


R语言 mclapply 位于 parallel 包(package)。

说明

mclapplylapply 的并行化版本,它返回与 X 相同长度的列表,其中每个元素是将 FUN 应用于 X 的相应元素的结果。

它依赖于分叉,因此在 Windows 上不可用,除非 mc.cores = 1

mcmapplymapply 的并行化版本,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

向量(原子或列表)或表达式向量。其他对象(包括分类对象)将被 as.list 强制。

FUN

... 并行应用于 ( mclapply ) X 或 ( mcmapply ) 每个元素的函数。

f

... 并行应用的函数。

...

对于 mclapplyFUN 的可选参数。对于 mcmapplymcMap 、向量或列表输入:请参阅 mapply

MoreArgs, SIMPLIFY, USE.NAMES

请参阅mapply

mc.preschedule

如果设置为TRUE,则计算首先被划分为(最多)与核心数量相同的作业,然后启动作业,每个作业可能涵盖多个值。如果设置为 FALSE ,则为 X 的每个值分叉一个作业。前者更适合短计算或 X 中的大量值,后者更适合完成时间差异较大且与 mc.cores 相比 X 值不多的作业。

mc.set.seed

请参阅mcparallel

mc.silent

如果设置为TRUE然后所有输出都在‘标准输出' 对于所有分叉的并行进程将被抑制('标准错误’不受影响)。

mc.cores

要使用的核心数量,即最多同时运行多少个子进程。该选项是从环境变量初始化的MC_CORES如果设置。必须至少为一,并且并行化至少需要两个核心。

mc.cleanup

如果设置为 TRUE ,则在此函数返回之前,所有已被该函数分叉的子进程都将被杀死(通过发送 SIGTERM )。正常情况下mclapply等待子进程传递结果,因此该选项通常仅在mclapply被中断时有效。如果设置为FALSE,则收集子进程,但不会强制终止。作为特殊情况,此参数可以设置为用于杀死子进程的信号编号,而不是 SIGTERM

mc.allow.recursive

除非 true,否则在子进程中调用 mclapply 将使用子进程,而不会再次 fork。

affinity.list

一个向量(原子或列表),包含 X 的每个元素的 CPU 亲和性掩码。 CPU 关联掩码说明了允许给定项目在哪个 CPU(核心或超线程单元)上运行,请参阅 mcaffinity 。要使用此参数,必须停用预调度 (mc.preschedule = FALSE)。

细节

mclapplylapply 的并行版本,提供 mc.cores > 1 :对于 mc.cores == 1 (并且 affinity.listNULL ),它只需调用 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 集群会更安全(请参阅makeClusterclusterApply)。

例子


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.

也可以看看

mcparallelpvecparLapplyclusterMap

simplify2array 用于类似 sapply 的结果。

相关用法


注:本文由纯净天空筛选整理自R-devel大神的英文原创作品 Parallel Versions of lapply and mapply using Forking。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。