2017-07-24 54 views
2

我運行以下示例代碼以模擬值,下面是4個內核的使用情況快照。需要一段時間才能全部使用所有核心,我想了解正在發生的事情,最終如何使其更快。r doParallel qbeta vs RcppParallel - 如何在滿容量時使用內核

library(doParallel) 
library(data.table) 

data<-data.table(a=runif(10000000),b=runif(10000000),quantile=runif(10000000)) 

e <- nrow(data)%/%1000000+1 
dataSplit<-split(data[],seq_len(nrow(data))%/%1000000) 
qbetaVec<-function(lossvalues) qbeta(lossvalues$quantile,lossvalues$a,lossvalues$b) 

cl <- makeCluster(4) 
registerDoParallel(cl) 
res2<-foreach(i=1:e) %dopar% qbetaVec(dataSplit[[i]]) 
res3<-unlist(res2) 

在我的機器上完成大約需要67秒。在res2運行時,我看了一下性能監視器,看起來需要一段時間才能全部使用全部4個內核。我想了解這是什麼原因。這是不可避免的嗎?在所有內核全部使用之前發生了什麼?用RcppParallel試試這個會更快嗎?

enter image description here

+0

這是一個玩具的例子嗎?因爲無需並行化就可以使其更快。 – Roland

+0

@Roland我自己使用qbeta,因爲它是矢量化的,速度更快(大約2倍)。編號喜歡看看並行化是否可以進一步改善它。 – charliealpha

回答

1

並行化涉及的開銷,尤其是數據的轉移和從工人。另外,如果您只使用四名工作人員,而且每項任務的時間都相當長,則將其分解爲四項以上任務是沒有意義的。

library(microbenchmark) 

microbenchmark(
    OP = { 
    e <- nrow(data)%/%1000000+1 
    dataSplit<-split(data[],seq_len(nrow(data))%/%1000000) 
    qbetaVec<-function(lossvalues) qbeta(lossvalues$quantile,lossvalues$a,lossvalues$b) 

    cl <- makeCluster(4) 
    registerDoParallel(cl) 
    res2<-foreach(i=1:e) %dopar% qbetaVec(dataSplit[[i]]) 
    res3<-unlist(res2) 
    stopCluster(cl) 
    }, 
    OP_4split = { 
    e <- 4 
    dataSplit<-split(data[],seq_len(nrow(data)) %% e) #note this change 
    qbetaVec<-function(lossvalues) qbeta(lossvalues$quantile,lossvalues$a,lossvalues$b) 

    cl <- makeCluster(e) 
    registerDoParallel(cl) 
    res2<-foreach(i=1:e) %dopar% qbetaVec(dataSplit[[i]]) 
    res3<-unlist(res2) 
    stopCluster(cl) 
    }, 
    serial = { 
    res3 <- data[, qbeta(quantile, a, b)] 
    }, 
    times = 3 
) 

#Unit: seconds 
#  expr  min  lq  mean median  uq  max neval 
#  OP 17.31950 17.35962 17.37491 17.39975 17.40262 17.40549  3 
# OP_4split 15.98415 16.03414 16.10776 16.08413 16.16957 16.25500  3 
# serial 22.62642 22.64165 22.66247 22.65689 22.68050 22.70411  3 

它只有4塊更好。但是,真的有很多數據需要傳輸和重新組合。分割數據也是一項成本高昂的操作。我不打擾並行化在這裏。

+0

感謝您的意見。我可以問你使用什麼處理器?它比時間快4倍。我也應該考慮改進硬件。 – charliealpha

+0

關於分割的數據,我試了這個,而不是節省時間,但不知道:e <-nrow(data)%/%100000 data [,grp:= seq_len(.N)%/%100000] res2 <-foreach i = 0:e,.packages =「data.table」)%dopar%qbetaVec(data [grp == i]) – charliealpha

+0

@charliealphan i7-4790K @ 4.00GHz – Roland