R語言中的並行計算

衆所周知,在大數據時代R語言有兩個弱項,其中一個就是隻能使用單線程計算。但是R在2.14版本之後,R就內置了parallel包,強化了R的並行計算能力。

parallel包實際上整合了之前已經比較成熟的snow包和multicore包,multicore無法在windows下運行。parallel包可以很容易的在計算集羣上實施並行計算,在多個CPU核心的單機上,也能發揮並行計算的功能。我們今天就來探索一下parallel包在多核心單機上的使用。

parallel包的思路和lapply函數很相似,都是將輸入數據分割、計算、整合結果。只不過並行計算是用到了不同的cpu來運算。

這樣的計算過程可以使用如下方式來表述:
1、啓動M個附屬進程,並初始化
2、針對於任務,爲每個附屬進程分發所有的數據
3、將任務粗略的分爲M個塊兒(chunks),並將這些塊兒發送到附屬進程(包含需要的R代碼)
4、等待所有的附屬進程完成計算任務,並返回結果
5、對於其他任務也同樣重複2-4
6、關閉附屬進程

在parallel包裏,對應上述兩種並行化方式有如下兩個核心函數(針對於lapply函數的並行化,mclapply在windows上不能使用):

parLapply(cl, x, FUN, …)
mclapply(X, FUN, …, mc.cores)

案例1、不使用並行計算,直接使用lapply(隱式循環函數,它實際就是對不同的數據應用了相同的函數):

parLapply(cl, x, FUN, ...)
mclapply(X, FUN, ..., mc.cores)

案例1、不使用並行計算,直接使用lapply(隱式循環函數,它實際就是對不同的數據應用了相同的函數):

fun <- function(x){
return (x+1);
}

system.time({
res <- lapply(1:5000000, fun);
});

user system elapsed
21.42 1.74 25.70
案例2、使用parallel包來加速

library(parallel)
#打開四核,具體核數根據機器的核數決定
cl <- makeCluster(getOption("cl.cores", 4));
system.time({
res <- parLapply(cl, 1:5000000,  fun)
});
user system elapsed
6.54 0.34 19.95
#關閉並行計算
stopCluster(cl);

看看單核機器跑出來的結果:
user system elapsed
29.30 9.23 97.22

所以,並非核數越多越好,看機器配置。

這個函數有兩點要注意:

首先要先用detectCores函數確定系統核心數目,對於Window系統下的Intel I5或I7 處理器,一般使用detectCores(logical = F)來獲得實際的物理核心數量。
由於這個函數使用的是調用Rscript的方式,這個例子裏,對象被複制了三份,因此內存會吃的很厲害,在大數據條件就要小心使用。

案例3、在Linux下使用mclapply函數的效果如下:

mc <- getOption("mc.cores", 3)
system.time({
res <- mclapply(1:5000000, fun, mc.cores = mc);
});
user system elapsed
6.657 0.500 7.181

foreach包是revolutionanalytics公司貢獻給R開源社區的一個包,它能使R中的並行計算更爲方便。與sapply函數類似,foreach函數中的第一個參數是輸入參數,%do%後面的對象表示運算函數,而.combine則表示運算結果的整合方式。 下面的例子即是用foreach來完成前面的同一個任務。如果要啓用並行,則需要加載doParallel包,並將%do%改爲%dopar%。這樣一行代碼就能方便的完成並行計算了。

案例4、foreach包的使用:

library(foreach)
# 非並行計算方式,類似於sapply函數的功能
x <- foreach(x=1:1000,.combine='rbind') %do% func(x)
# 啓用parallel作爲foreach並行計算的後端
library(doParallel)
cl <- makeCluster(4)
registerDoParallel(cl)
# 並行計算方式
x <- foreach(x=1:1000,.combine='rbind') %dopar% func(x)
stopCluster(cl)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章