foreach () сборка мусора - PullRequest
       16

foreach () сборка мусора

6 голосов
/ 03 ноября 2011

Я использую вложенный foreach из пакета doSMP для генерации результатов на основе разработанной мной функции.Обычно проблема заключалась бы в использовании трех вложенных циклов, но из-за размера сгенерированных результатов (около 80 000 для каждого i) мне пришлось приостановить компиляцию и записать результаты в файл, когда окончательная матрица результатов превысит указанное число строк.

i = 1
write.off = 1

while(i <= length(i.vector)){
        results.frame = as.data.frame(matrix(NA, ncol = 3, nrow = 1))

        while(nrow(results.frame) < 500000 & i <= length(i.vector)){
                results = foreach(j = 1:length(j.vector), .combine = "rbind", .inorder = TRUE) %:%
                foreach(k = 1:length(k.vector), .combine = "rbind", .inorder = TRUE) %dopar%{

                        ith.value = i.vector[i]
                        jth.value = j.vector[j]
                        kth.value = k.vector[k]
                        my.function(ith.value, jth.value, kth.value)
                }

                results.frame = rbind(results.frame, results)
                i = i + 1
        }

        results.frame = results.frame[-1,]
        write.table(results.frame, paste("part_",write.off, sep = ""))
        write.off = write.off + 1   
}

У меня проблема с сборкой мусора.Похоже, что рабочие не перераспределяют память обратно в систему, поэтому при i = 4 каждый из них съел около 6 ГБ памяти.

Я попытался вставить gc () в цикл foreach напрямую, а также в базовую функцию, и я также попытался назначить функцию и ее результаты именованной среде, которую я могу периодически очищать.Ни один из этих методов не сработал.

Мне кажется, что параметры initEnvir и finalEnvir в foreach могут предложить решение, но документация и примеры на самом деле не проливают свет на это.

Я запускаю этот код на виртуальной машине, работающейWindows Server 2008.

1 Ответ

0 голосов
/ 03 ноября 2011

Возможно, вы решите вообще избежать этой проблемы, написав другой цикл.

Рассмотрите возможность использования функции gen.factorial в AlgDesign, например:

fact1 = gen.factorial(c(length(i.vector), length(j.vector), length(k.vector)), nVars = 3, center = FALSE)
foreach(ix_row = 1:nrow(fact1)) %dopar% {
  my.function(fact1[ix_row,])
}

Вы также можете использовать файлы с отображенной памятью и предварительно выделить хранилище вывода, используя bigmemory (при условии, что вы создаете матрицу), и это позволит каждому работнику сохранять свои выходные данные самостоятельно.

Таким образом, общее использование памяти должно резко упасть.


Обновление 1: похоже, проблемы с памятью свойственны doSMP. Проверьте следующие сообщения:

Я помню, что видел еще одну проблему с памятью для doSMP, либо в виде вопроса, либо в чате R, но я не могу восстановить сообщение.

Обновление 2: я не знаю, поможет ли это, но вы можете попробовать использовать явный return() (например, return(my.function(ith.value, jth.value, kth.value))). В моем коде я обычно использую явный return() для ясности.

...