Это может быть один для философов ... (или @Steve Weston или @Martin Morgan)
У меня были некоторые проблемы с утечками памяти при использовании parLapply, и после того, как я перекопал достаточно потоков наДело в том, я думаю, что этот вопрос вполне оправдан.Я потратил некоторое время, чтобы попытаться выяснить это, и хотя у меня есть подсказка о том, почему происходит наблюдаемое поведение, я теряюсь в том, как его решить.
Рассмотрим следующее как исходный сценарий, сохраненный как: parallel_question.R
rf.parallel<-function(n=10){
library(parallel)
library(randomForest)
rf.form<- as.formula(paste("Final", paste(c('x','y','z'), collapse = "+"), sep = " ~ "))
rf.df<-data.frame(Final=runif(10000),y=runif(10000),x=runif(10000),z=runif(10000))
rf.df.list<-split(rf.df,rep(1:n,nrow(rf.df))[1:nrow(rf.df)])
cl<-makeCluster(n)
rf.list<-parLapply(cl,rf.df.list,function(x,rf.form,n){
randomForest::randomForest(rf.form,x,ntree=100,nodesize=10, norm.votes=FALSE)},rf.form,n)
stopCluster(cl)
return(rf.list)
}
Мы создаем и запускаем сценарий с помощью:
scrip.loc<-"G:\\Scripts_Library\\R\\Stack_Answers\\parallel_question.R"
source(scrip.loc)
rf.parallel(n=10)
Довольно просто ... мы запустили несколько случайныхлес параллельно.Кажется, эффективная память.Мы могли бы объединить их позже или сделать что-то еще.Handy.Ницца.Хорошо себя ведет.
Теперь рассмотрим следующий сценарий, сохраненный как parallel_question_2.R
rf.parallel_2<-function(n=10){
library(parallel)
library(magrittr)
library(randomForest)
rf.form<- as.formula(paste("Final", paste(c('x','y','z'), collapse = "+"), sep = " ~ "))
rf.df<-data.frame(Final=runif(10000),y=runif(10000),x=runif(10000),z=runif(10000))
large.list<-rep(rf.df,10000)
rf.df.list<-split(rf.df,rep(1:n,nrow(rf.df))[1:nrow(rf.df)])
cl<-makeCluster(n)
rf.list<-parLapply(cl,rf.df.list,function(x,rf.form,n){
randomForest::randomForest(rf.form,x,ntree=100,nodesize=10, norm.votes=FALSE)},rf.form,n)
stopCluster(cl)
return(rf.list)
}
Во втором сценарии мы получили большой список в нашей исходной среде.Мы не вызываем список и не вносим его в нашу параллельную функцию.Я установил размер списка, чтобы он, вероятно, был проблемой, по крайней мере, на 32-гигабайтной машине.
scrip.loc<-"G:\\Scripts_Library\\R\\Stack_Answers\\parallel_question_2.R"
source(scrip.loc)
rf.parallel_2(n=10)
Когда мы запускаем второй скрипт, мы получаем ~ 3 ГБ (размер нашего большогоlist) * количество рабочих потоков, установленных для кластера, дополнительный материал вокруг.Если мы запускаем содержимое второго скрипта в среде без источников, это не поведение;скорее, мы получаем один ~ 3 ГБ список, распараллеленная функция выполняется без проблем, и на этом все.
Итак ... как / почему рабочие среды отбирают элементы ненужных переменных из родительской среды?Почему это происходит только в сценариях с источником?Как я могу смягчить это, когда у меня есть большой и сложный сценарий с источником, который имеет параллельные части (но может иметь 3-10 ГБ промежуточных данных, переносимых вокруг)?
Соответствующие или похожие потоки:
Использование parLapply и clusterExport внутри функции
clusterExport, среда и область видимости переменных