2012-07-23 100 views
4

我想獲得的foreach包進行並行處理R中的工作,我有幾個問題:DOMC在R和foreach循環不工作

所作出的foreach工作所需的DOMC包不存在於CRAN for Windows上。有些博客建議doSNOW應該做同樣的工作。但是,當我使用doSNOW運行foreach命令時,%dopar%似乎沒有比%do%快。實際上它慢得多。我的CPU是帶有8 GB RAM的Intel i7 860 @ 2.80GHz。下面是我的代碼:

##Run example in 1 core 
require(foreach) 
require(doSNOW) 
x= iris[which(iris[,5] != "setosa"),c(1,5)] 
trials = 10000 
system.time({ 
r= foreach(icount(trials), .combine=cbind) %do% { 
ind=sample(100,100,replace=TRUE) 
results1 = glm(x[ind,2]~x[ind,1],family=binomial(logit)) 
coefficients(results1) 
} 
})[3] 
# elapsed 
# 37.28 

# Same example in 2 cores 
registerDoSNOW(makeCluster(2,type="SOCK")) 
getDoParWorkers() 
trials = 10000 
system.time({ 
r= foreach(icount(trials), .combine=cbind) %dopar% { 
ind=sample(100,100,replace=TRUE) 
results1 = glm(x[ind,2]~x[ind,1],family=binomial(logit)) 
coefficients(results1) 
} 
})[3] 
# elapsed 
# 108.14 

我重新安裝了所有所需的軟件包,但還是同樣的問題。下面是輸出:

sessionInfo() 

#R version 2.15.1 (2012-06-22) 
#Platform: i386-pc-mingw32/i386 (32-bit) 

#locale: 
#[1] LC_COLLATE=English_United States.1252 
#[2] LC_CTYPE=English_United States.1252 
#[3] LC_MONETARY=English_United States.1252 
#[4] LC_NUMERIC=C       
#[5] LC_TIME=English_United States.1252  

#attached base packages: 
#[1] parallel stats  graphics grDevices datasets utils  methods 
#[8] base  

#other attached packages: 
#[1] doParallel_1.0.1 codetools_0.2-8 doSNOW_1.0.6  snow_0.3-10  
#[5] iterators_1.0.6 foreach_1.4.0 rcom_2.2-5  rscproxy_2.0-5 

#loaded via a namespace (and not attached): 
#[1] compiler_2.15.1 tools_2.15.1 
+0

運行R-2.15.1,doSNOW_1.0.5,snow_0.3-8,foreach_1.3.2,codetools_0.2-8和iterators_1.0.5的''%dopar%''示例運行速度更快。你機器上'sessionInfo'的輸出是什麼? – 2012-07-23 17:50:03

+0

請編輯您的問題並添加該信息。閱讀起來會更容易。 – 2012-07-24 17:12:26

回答

4

您在Windows中最好使用doParallel()

require(foreach) 
require(doParallel) 
cl <- makeCluster(6) #use 6 cores, ie for an 8-core machine 
registerDoParallel(cl) 

然後運行foreach() %dopar% {}

編輯:OP提到的還是看到了問題,所以包括我的確切碼。運行在4核Windows7的虛擬機,R 2.15.1 32位,只允許doParallel用我的核心3:

require(foreach) 
require(doParallel) 
cl <- makeCluster(3) 
registerDoParallel(cl) 

x= iris[which(iris[,5] != "setosa"),c(1,5)] 

trials = 1000 
system.time( 
    foreach(icount(trials), .combine=cbind) %do% 
    { 
    ind=sample(100,100,replace=TRUE) 
    results1 = glm(x[ind,2]~x[ind,1],family=binomial(logit)) 
    results1 = glm(x[ind,2]~x[ind,1],family=binomial(logit)) 
    results1 = glm(x[ind,2]~x[ind,1],family=binomial(logit)) 
    results1 = glm(x[ind,2]~x[ind,1],family=binomial(logit)) 
    coefficients(results1) 
    })[3] 

system.time( 
    foreach(icount(trials), .combine=cbind) %dopar% 
    { 
    ind=sample(100,100,replace=TRUE) 
    results1 = glm(x[ind,2]~x[ind,1],family=binomial(logit)) 
    results1 = glm(x[ind,2]~x[ind,1],family=binomial(logit)) 
    results1 = glm(x[ind,2]~x[ind,1],family=binomial(logit)) 
    results1 = glm(x[ind,2]~x[ind,1],family=binomial(logit)) 
    coefficients(results1) 
    })[3] 

在我的情況,我得到17.6秒,%do%和14.8秒, %dopar%。看着任務執行,看起來執行時間的大部分是cbind,這是一個並行運行的常見問題。在我自己的模擬中,我已經完成了定製工作,將我的詳細結果保存爲並行任務的一部分,而不是通過返回foreach來消除這部分開銷。因人而異。

+0

感謝您的幫助。仍然有問題... – 2012-07-24 17:12:42

+0

這工作!是否有可能解釋爲什麼%dopar%循環中的代碼需要重複複製?代碼複製的次數是否重要?感謝您的幫助! – 2012-07-25 17:25:41

+0

複製代碼是從@ Dieter的答案中複製的。也許他可以解釋它。 – khoxsey 2012-07-25 19:07:13

2

這種類型的並行性並不是非典型的,並且可能取決於操作系統。我有類似的結果如你,但是當我做了在代碼

require(foreach) 
require(doSNOW) 

x= iris[which(iris[,5] != "setosa"),c(1,5)] 

trials = 1000 
system.time( 
    foreach(icount(trials), .combine=cbind) %do% 
    { 
    ind=sample(100,100,replace=TRUE) 
    results1 = glm(x[ind,2]~x[ind,1],family=binomial(logit)) 
    results1 = glm(x[ind,2]~x[ind,1],family=binomial(logit)) 
    results1 = glm(x[ind,2]~x[ind,1],family=binomial(logit)) 
    results1 = glm(x[ind,2]~x[ind,1],family=binomial(logit)) 
    coefficients(results1) 
    })[3] 


registerDoSNOW( makeCluster(2,type="SOCK")) 
getDoParWorkers() 
trials = 1000 
system.time(
    foreach(icount(trials), .combine=cbind) %dopar% 
    { 
    ind=sample(100,100,replace=TRUE) 
    results1 = glm(x[ind,2]~x[ind,1],family=binomial(logit)) 
    results1 = glm(x[ind,2]~x[ind,1],family=binomial(logit)) 
    results1 = glm(x[ind,2]~x[ind,1],family=binomial(logit)) 
    results1 = glm(x[ind,2]~x[ind,1],family=binomial(logit)) 
    coefficients(results1) 
    })[3] 

一個愚蠢的變化來模擬在foreach繁重的工作,我得到了一個盈虧平衡兩者。這是開銷的代價。我最近有一個類似的案例,並直接與MPI進行處理,MPI開銷較低,但使用起來要複雜得多(我認爲Dirk會不同意)。 (更改爲「更不優雅」

+0

感謝您的幫助。它可能確實取決於操作系統,因爲%dopar%在另一個操作系統上運行得更快。再次感謝!! – 2012-07-24 17:19:20

3

我知道這是一個較老的問題,但我在搜索其他東西時發現它,並認爲我會添加我的解決方案。 (試驗組的數量等於處理器內核的數量),而不是試圖一次性並行所有試驗並處理所有開銷。下面是使用OP示例的一個比較:

上運行Ubuntu 12.04 3.4 GHz四核i7
require(doParallel) 

x <- iris[which(iris[,5] != "setosa"),c(1,5)] 
trials <- 10000 

# example using a single core 
t1 <- system.time({ 
    r1 <- foreach(icount(trials), .combine=cbind) %do% { 
    ind <- sample(100,100,replace= TRUE) 
    results1 <- glm(x[ind,2]~x[ind,1],family=binomial(logit)) 
    coefficients(results1) 
    } 
})[3] 

# example using 4 cores and parallelizing each model trial 
nCores <- 4 
cl <- makeCluster(nCores) 
registerDoParallel(cl) 

t2 <- system.time({ 
    r2 <- foreach(icount(trials), .combine=cbind) %dopar% { 
    ind <- sample(100,100,replace= TRUE) 
    results1 <- glm(x[ind,2]~x[ind,1],family=binomial(logit)) 
    coefficients(results1) 
    } 
})[3] 

# example using 4 cores and parallelizing a group of trial runs 
trialsPerCore <- as.integer(ceiling(trials/nCores)) # number of trials 
                # do to on each core 
# function to do a single model run 
model <- function(x) { 
    ind <- sample(100,100,replace= TRUE) 
    results1 <- glm(x[ind,2]~x[ind,1],family=binomial(logit)) 
    coefficients(results1) 
} 
# function producing a group of model runs 
modelRun <- function(trials, x) { 
    replicate(trials, model(x)) 
} 
# call the model run for each core 
t3 <- system.time(
    r3 <- foreach(icount(nCores), .combine= cbind) %dopar% modelRun(trialsPerCore, x) 
)[3] 

stopCluster(cl) 

執行時間:

> t1 
elapsed 
    34.5 
> t2 
elapsed 
    26.5 
> t3 
elapsed 
    8.295 
+0

謝謝pistachionut,我正在尋找這樣的東西。這個實現在linux上工作嗎?我會盡快對它進行測試。如果是這樣,如果它是一個僅限Windows或跨平臺的解決方案,則可能需要明確地寫入。 – PatrickT 2013-03-06 15:14:08