當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


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。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。