簡體   English   中英

有沒有辦法在R中進行並行計算時釋放內存

[英]is there a way to release the memory when do parallel computation in R

假設我想使用多個核運行R程序,如下所示

library(foreach)
library(doParallel)

no_cores <- detectCores() - 2

cl<-makeCluster(no_cores, outfile = "debug.txt")

registerDoParallel(cl)

result <- foreach(i = 10:100, 
        .combine = list,
        .multicombine = TRUE)  %dopar%  {

          set.seed(i)

          a <- replicate(i, rnorm(20)) 
          b <- replicate(i, rnorm(20))

          list(x = a + b, y = a - b)

        } 

但是,我發現程序運行一段時間后內存使用量增加了。 我認為該程序不會釋放舊對象。 所以我嘗試使用gc()作為

result <- foreach(i = 10:100, 
        .combine = list,
        .multicombine = TRUE)  %dopar%  {

          set.seed(i)

          a <- replicate(i, rnorm(20)) 
          b <- replicate(i, rnorm(20))

          list(x = a + b, y = a - b)
         gc()

        } 

它似乎有用,但我沒有得到我想要的結果。 然后我嘗試在每個循環之前收集垃圾,但似乎不起作用。

result <- foreach(i = 10:100, 
        .combine = list,
        .multicombine = TRUE)  %dopar%  {
          gc()
          set.seed(i)

          a <- replicate(i, rnorm(20)) 
          b <- replicate(i, rnorm(20))

          list(x = a + b, y = a - b)    
        } 

有沒有辦法解決這個問題? 謝謝你們,任何建議將不勝感激。 PS。 這段代碼只是為了重現,我的真實模擬程序比這復雜得多。 所以我不想太多地改變程序結構。

我認為你沒有遇到任何所謂的“內存泄漏”,因為使用foreach更多迭代只會創建一個更大的數組。 如果你的問題是gc()是否真的有用,我建議你閱讀Hadley Wickham的Advanced R的內存使用章節,其中他說:

盡管你可能已經在其他地方讀到過,但是從來沒有必要自己調用gc()

無論如何,我試圖找出代碼中可能存在的內存泄漏,將其分為您描述的三個函數或可能性。

library(foreach)
library(doParallel)  
f1 <- function(uu = 10:100){
  no_cores <- detectCores() - 2
  cl<-makeCluster(no_cores)
  registerDoParallel(cl)
  result1 <- foreach(i = uu, .combine = list, 
                     .multicombine = TRUE)  %dopar%  {
                      set.seed(i)
                      a <- replicate(i, rnorm(20)) 
                      b <- replicate(i, rnorm(20))
                      gc()
                      return(list(x = a + b, y = a - b))
                      } 
  stopCluster(cl)
  return(result1)
}
f2 <- function(uu = 10:100){
  no_cores <- detectCores() - 2
  cl<-makeCluster(no_cores)
  registerDoParallel(cl)
  result1 <- foreach(i = uu, .combine = list, 
                     .multicombine = TRUE)  %dopar%  {
                       gc()
                       set.seed(i)
                       a <- replicate(i, rnorm(20)) 
                       b <- replicate(i, rnorm(20))
                       return(list(x = a + b, y = a - b))
                     } 
  stopCluster(cl)
  return(result1)
}
f3 <- function(uu = 10:100){
  no_cores <- detectCores() - 2
  cl<-makeCluster(no_cores)
  registerDoParallel(cl)
  result1 <- foreach(i = uu, .combine = list,  .multicombine = TRUE)  %dopar%  {
                       set.seed(i)
                       a <- replicate(i, rnorm(20)) 
                       b <- replicate(i, rnorm(20))
                       return(list(x = a + b, y = a - b))
                     } 
  stopCluster(cl)
  return(result1)
}

library(pryr)
mem_used() # 214 MB
mem_change(NULL) # 864 B
gc() # whatever
mem_change({res1 <- f1(); rm(res1)}) # 2.11 kB
mem_change({res1 <- f2(); rm(res1)}) # 2.11 kB
mem_change({res1 <- f3(); rm(res1)}) # 2.11 kB
mem_change({res1 <- f1(10:250); rm(res1)}) # 2.11 kB
mem_change({res1 <- f2(10:250); rm(res1)}) # 2.11 kB
mem_change({res1 <- f3(10:250); rm(res1)}) # 2.11 kB

除此之外,我嘗試使用標准輸入(10:100)運行三個函數的profvis ,我得到了以下一般時間和記憶:

F1(): 在此輸入圖像描述 F2(): 在此輸入圖像描述 F3(): 在此輸入圖像描述

我不相信profvis的記憶結果,但是時間。 一般來說,我不會使用gc()來釋放並行循環中的空間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM