假设我想使用多个核心运行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。这段代码只是为了重现,我的真实模拟程序比这复杂得多。所以我不想太多地改变程序结构。
答案 0 :(得分:1)
我认为您没有遇到任何所谓的“内存泄漏”,因为使用foreach
的更多迭代只会创建更大的数组。如果您的问题是gc()
是否真的有用,我建议您阅读Hadley Wickham撰写的Advanced R的memory usage一章,他在其中指出:
尽管您可能在其他地方已经读过书,但无需亲自打电话给
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
此外,我尝试在具有std输入(10:100)的三个函数上运行profvis
,并且得到了以下一般时间和记忆:
我不愿意将profvis
的结果用于记忆,但是会浪费时间。通常,我不会使用gc()
来释放并行循环中的空间。