snow包主要運(yùn)行于傳統(tǒng)的集群計(jì)算。它主要用于蒙特卡洛模擬(Monte Carlo simulations),boostrapping,交叉驗(yàn)證(cross validation),集成機(jī)器學(xué)習(xí)算法(ensemble machine learning algorithms)和K均值聚類(lèi)(K-Means clustering)等,并且也很好支持并行隨機(jī)數(shù)的生成。 snow包的安裝一般應(yīng)用install.packages('snow')
. 要使用snow包進(jìn)行并行運(yùn)算,首先要?jiǎng)?chuàng)建一個(gè)集群對(duì)象,主要用于與內(nèi)核的交互,一般傳遞與snow包中函數(shù)的第一個(gè)參數(shù)。 基本的集群創(chuàng)建函數(shù)為makeCluster(),它能創(chuàng)建任何類(lèi)型的集群,例如,在本地機(jī)器上創(chuàng)建一個(gè)4核的集群:
第一個(gè)參數(shù)為集群設(shè)定,即設(shè)定使用的CPU數(shù);第二個(gè)參數(shù)是集群類(lèi)型。 注意:在結(jié)束集群時(shí)使用stopCluster()
。 下面使用snow包做一個(gè)并行運(yùn)算。
數(shù)據(jù)是MASS包自帶的Boston數(shù)據(jù)集。 K均值函數(shù)使用stats包中的kmeans()。
library(MASS)result <- kmeans(Boston, 4, nstart = 100)在使用并行計(jì)算前,首先看看使用lapply函數(shù)的運(yùn)行情況
results <- lapply(rep(25,4), function(nstart) kmeans(Boston, 4, nstart = nstart)i <- sapply(results, function(result) result$tot.withiness)result <- results[[which.min(i)]]相比較clusterEvalQ
而言,clusterCall
更好用,它的第一個(gè)參數(shù)為集群對(duì)象,第二個(gè)參數(shù)為一個(gè)函數(shù),并且其他的參數(shù)可以傳遞給這個(gè)函數(shù)。最終返回一個(gè)列表。
clusterCall函數(shù)可以調(diào)用多個(gè)包,
worker.init <- function(packages) {for (p in packages) {library(p, character.only=TRUE)}NULL}clusterCall(cl, worker.init, c('MASS', 'boot'))character.only=TRUE
是使library把參數(shù)解釋為字符向量,否則library會(huì)重復(fù)載入名稱(chēng)為p的包。
clusterApplyLB與clusterApply函數(shù)相似,但clusterApplyLB的運(yùn)行效率更高。在使用clusterApply并行運(yùn)算時(shí),如果每一個(gè)內(nèi)核花費(fèi)不同的時(shí)間進(jìn)行運(yùn)算,那么在那個(gè)運(yùn)行時(shí)間長(zhǎng)的內(nèi)核結(jié)束之前,運(yùn)行時(shí)間短的內(nèi)核不能進(jìn)行下一次運(yùn)算,而clusterApplyLB不同,它是在運(yùn)行時(shí)間短的內(nèi)核結(jié)束之后接著就運(yùn)行下一次的運(yùn)算,這樣就減少了時(shí)間的浪費(fèi),因此提高了效率。 為了說(shuō)明clusterApplyLB的效率,我們使用控制任務(wù)時(shí)間長(zhǎng)度的函數(shù)Sys.sleep。用snow.time收集整個(gè)執(zhí)行過(guò)程的時(shí)間信息。
set.seed(7777442)sleeptime <- abs(rnorm(10, 10, 10))tm <- snow.time(clusterApplyLB(cl, sleeptime, Sys.sleep))plot(tm) 作為對(duì)照,我們用clusterApply函數(shù)來(lái)觀察運(yùn)行時(shí)間
由此看出clusterApplyLB效率更高。
parLapply是snow包中的一個(gè)高級(jí)函數(shù),它比clusterApply函數(shù)更高效,如果參數(shù)x的長(zhǎng)度與內(nèi)核的數(shù)量相等,parLapply的優(yōu)勢(shì)不明顯,如果參數(shù)x的長(zhǎng)度遠(yuǎn)大于內(nèi)核的數(shù)量,parLapply相比于clusterApply是一個(gè)更好的選擇。 應(yīng)用一個(gè)并行休眠函數(shù)的用法,首先使用clusterApply
bigsleep <- function(sleeptime, mat) Sys.sleep(sleeptime)bigmatrix <- matrix(0, 2000, 2000)sleeptime <- rep(1, 100)tm2 <- snow.time(clusterApply(cl, sleeptime, bigsleep, bigmatrix))plot(tm2) 由圖看出并不高效,因?yàn)橛写罅康妮斎胼敵鰰r(shí)間,下面再試一試clusterApplyLB:
由上圖看出,運(yùn)算集中在第1、2和3個(gè)內(nèi)核上,第4個(gè)內(nèi)核上運(yùn)算的時(shí)間非常少,及運(yùn)算效率差,但總體還是比clusterApply函數(shù)要好一些。 看看最終的函數(shù)parLapply:
由此看出,傳輸交換的時(shí)間大大縮短了,因此提高了效率。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注