Профилирование памяти в R: как найти место максимального использования памяти? - PullRequest
2 голосов
/ 05 октября 2019

Мой код съедает до 3 ГБ памяти за один раз. Я понял это, используя gc():

gc1 <- gc(reset = TRUE)
graf(...) # the code
gc2 <- gc()
cat(sprintf("mem: %.1fMb.\n", sum(gc2[,6] - gc1[,2])))
# mem: 3151.7Mb.

Что, я думаю, означает, что есть один раз, когда выделяется 3151,7 МБ за один раз.

Моя цель - минимизировать максимумпамять выделяется в любой момент времени. Как определить, какая часть моего кода отвечает за максимальное использование этих 3 ГБ памяти? Т.е. место, где эти 3 ГБ выделяются одновременно.

  1. Я попытался профилировать память с помощью Rprof и profvis, но оба, похоже, показывают различную информацию (которая кажется недокументированной, см. мой другой вопрос ). Может быть, мне нужно использовать их с разными параметрами (или использовать другой инструмент?).

  2. Я смотрел на Rprofmem ... но:

1 Ответ

0 голосов
/ 14 октября 2019

Мой код съедает до 3 ГБ памяти за один раз.

Хотя похоже, что ваш код потребляет много оперативной памяти одновременно, вызывая одну функцию, которую можно сломатьпотребление памяти путем изучения подробностей реализации функции (и ее дополнительных вызовов) с помощью встроенного профилирования RStudio (на основе profvis), чтобы увидеть время выполнения и приблизительное потребление памяти. Например. если я использую свой демонстрационный код:

  # graf code taken from the tutorial at
  # https://rawgit.com/goldingn/intecol2013/master/tutorial/graf_workshop.html
  library(dismo)  # install.packages("dismo")
  library(GRaF)   # install_github('goldingn/GRaF')

  data(Anguilla_train)

  # loop to call the code under test several times to get better profiling results
  for (i in 1:5) {

    # keep the first n records of SegSumT, SegTSeas and Method as covariates
    covs <- Anguilla_train[, c("SegSumT", "SegTSeas", "Method")]

    # use the presence/absence status to fit a simple model
    m1 <- graf(Anguilla_train$Angaus, covs)
  }

Запустите профилирование с помощью пункта меню Профиль> Начать профилирование , введите приведенный выше код и остановите профилирование через указанное меню.

После Профиль> Остановить профилирование RStudio показывает результат в виде графика пламени, но то, что вы ищете, скрыто на вкладке Данные результата профиля (я развернул все вызовы функцийкоторые показывают интенсивное использование памяти):

enter image description here

Числа в столбце memory указывают на выделенную память (положительную) и освобожденную (отрицательные числа) длякаждая вызываемая функция и значения должны включать в себя сумму всего вспомогательного дерева вызовов + память, непосредственно используемую в функции.

Моя цель состоит в том, чтобы минимизировать максимальное количество памяти, выделяемое в любой момент времени.

Почему вы хотите это сделать? У вас не хватает памяти или вы подозреваете, что повторное выделение памяти вызывает длительное время выполнения?

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

Посмотрите на столбец Memory или Time в зависимости от ваших целей оптимизации, чтобы найти вызовы функций с высокими значениями.

Если вы посмотрите на исходный код GRaF В пакете вы можете найти цикл в функции graf.fit.laplace (до 50 «итераций Ньютона»), которая вызывает «медленные» R-внутренние функции, такие как chol, backsolve, forwardsolve, нотакже медленные функции, реализованные в самом пакете (например, cov.SE.d1).

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

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

Rprof имеет ограничения (в основном это не точный результат профилирования, поскольку сборщик мусора срабатывает в недетерминированное время, а освобожденная память приписывается функции следующейпрерывание интервала зондирования останавливается на и оно не распознает память, выделенную непосредственно из ОС через код / ​​библиотеки C / C ++, которые обходят API управления памятью R). Тем не менее, это самый простой и обычно достаточно хороший признак проблем с памятью и производительностью ...

Для ознакомления с profvis см .: Для https://rstudio.github.io/profvis/

...