2012-07-23 101 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