doParallel (package) foreach does not work for big iterations in R

前端 未结 2 812
梦如初夏
梦如初夏 2021-01-03 01:26

I\'m running the following code (extracted from doParallel\'s Vignettes) on a PC (OS Linux) with 4 and 8 physical and logical cores, respectively.

Running the code

2条回答
  •  天涯浪人
    2021-01-03 02:30

    At first I thought you were running into memory problems because submitting many tasks does use more memory, and that can eventually cause the master process to get bogged down, so my original answer shows several techniques for using less memory. However, now it sounds like there's a startup and shutdown phase where only the master process is busy, but the workers are busy for some period of time in the middle. I think the issue is that the tasks in this example aren't really very compute intensive, and so when you have a lot of tasks, you start to really notice the startup and shutdown times. I timed the actual computations and found that each task only takes about 3 milliseconds. In the past, you wouldn't get any benefit from parallel computing with tasks that small, but now, depending on your machine, you can get some benefit but the overhead is significant, so when you have a great many tasks you really notice that overhead.

    I still think that my other answer works well for this problem, but since you have enough memory, it's overkill. The most important technique to use chunking. Here is an example that uses chunking with minimal changes to the original example:

    require("doParallel")
    nw <- 8
    registerDoParallel(nw)
    x <- iris[which(iris[,5] != "setosa"), c(1,5)]
    niter <- 4e+6
    r <- foreach(n=idiv(niter, chunks=nw), .combine='rbind') %dopar% {
      do.call('rbind', lapply(seq_len(n), function(i) {
        ind <- sample(100, 100, replace=TRUE)
        result1 <- glm(x[ind,2]~x[ind,1], family=binomial(logit))
        coefficients(result1)
      }))
    }
    

    Note that this does the chunking slightly differently than my other answer. It only uses one task per worker by using the idiv chunks option, rather than the chunkSize option. This reduces the amount of work done by the master and is a good strategy if you have enough memory.

提交回复
热议问题