如何在doMC和foreach中使用biglm

时间:2013-05-15 23:44:00

标签: r foreach domc

是否可以在并行模式下运行biglm?我尝试使用doMC,然后在foreach循环中嵌入biglm,但似乎所有内核将同时处理同一块数据。我该如何并行化?

library(doMC)
RegisterDoMC(4)

require(ffbase)
sample <- read.table.ffdf(file="sample_output.csv", FUN = "read.csv", na.strings = "")  
library(biglm)
model<-list()
biglmupdate<-function(dataset,start,end) {
 if (start==1) {
    model <<- biglm(a~b+c, data=dataset[start:end,])
 }
 else {
    model <<- update(model,dataset[start:end,])
 }
}

chunks <- floor(dim(sample)[1]/220000)+1
start<-0; end<-0;
foreach (i = 1: chunks) %dopar% { 
    start = end +1; end =ifelse (i == chunks, dim(sample)[1], start+220000); 
    print(paste("chunk ",i," ",start,":",end," started at:", Sys.time()));
    biglmupdate(dataset = sample, start, end);
    print(paste("chunk ",i,"ended at:", Sys.time()));
}

1 个答案:

答案 0 :(得分:0)

我对biglm包不是很熟悉,但它看起来并不容易并行执行,因为它通过对模型对象的一系列更新来工作。这种循环从根本上是顺序的。例如,您无法并行化:

i <- 0
for (i in 1:10) {
    i <- i + 1
}

通过将十个不同的流程分别添加1i。循环取决于对i进行顺序更新。从我所看到的情况来看,biglm函数也是如此。

除了这个基本问题,我还会看到代码中的另外两个问题:startend的计算以及model的修改方式。如上例所示,当并行执行循环时,无法根据先前迭代的值计算循环变量的值。在这种情况下,可以通过将循环更改为:

来解决这个问题
n <- nrow(sample)
m <- 220000
foreach(start=seq(1,n,by=m), end=seq(m,n,by=m) %dopar% {
    # ...
}

startend的值都是预先计算的,因此并行执行循环没有问题。我怀疑这解决了导致您发表评论的问题,即所有核心都在处理同一块数据。不幸的是,这并没有解决并行执行biglm的基本问题。

model的问题在于您尝试从并行进程更新单个类似全局的变量。使用foreach时,您应该考虑从循环的每次迭代返回一个值并使用.combine函数处理它们。让主体修改循环外部的变量几乎总是失败。