Мониторинг использования памяти в R - PullRequest
36 голосов
/ 22 октября 2011

Можно ли контролировать объем памяти, который используется или использовался R для вызова функции?Например, у меня есть произвольная функция, например:

smallest.sv <- function(){
  A <- matrix(rnorm(1e6), 1e3);
  mysvd <- svd(A);
  return(tail(mysvd$d, 1));
}

Запуск функции просто возвращает скаляр, но для ее вычисления использовалось много памяти.Теперь мне нужно сделать тест производительности.Время обработки простое:

system.time(x <- smallest.sv())

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

Изменить: уточнить немного.Меня больше всего интересует верхняя граница памяти, которая использовалась во время вызова функции, то есть, сколько физической памяти требуется для обработки вызова функции.Я думаю, что во многих случаях это значительно меньше общего объема выделенной памяти.

Ответы [ 3 ]

20 голосов
/ 22 октября 2011

R обеспечивает поддержку профилирования памяти, см. Раздел 3.3 руководства по расширению Writing R :

3.3 Код R профилирования для использования памяти

Измерение использования памятив коде R полезно, когда код занимает больше памяти, чем удобно, или когда выделение памяти и копирование объектов отвечают за медленный код.Существует три способа профилирования использования памяти с течением времени в коде R.Все три требуют, чтобы R был скомпилирован с `--enable-memory-profiling ', который не используется по умолчанию, но в настоящее время используется для двоичных дистрибутивов Mac OS X и Windows.Все это может вводить в заблуждение по разным причинам.

Для понимания профилей памяти полезно узнать немного больше о выделении памяти R.Просмотр результатов `gc () 'показывает разделение памяти на` Vcells', используемое для хранения содержимого векторов, и `Ncells ', используемый для хранения всего остального, включая все административные издержки для векторов, такие как информация о типе и длине.Фактически векторное содержимое разделено на два пула.Память для маленьких векторов (по умолчанию 128 байтов или меньше) получается большими порциями и затем распределяется по R;память для больших векторов получается непосредственно из операционной системы.

, а затем предоставляет еще три раздела.

12 голосов
/ 22 октября 2011

Один из вариантов - использовать Rprof. Простой подход заключается в следующем:

Rprof(tf <- "rprof.log", memory.profiling=TRUE)

[your code]

Rprof(NULL)
summaryRprof(tf)

Это даст вам некоторую информацию об использовании памяти.

0 голосов
/ 08 июля 2019

Вы можете получить верхнюю границу памяти, которая используется при обработке функции и команд с gc:

smallest.sv <- function(){
  A <- matrix(rnorm(1e6), 1e3);
  mysvd <- svd(A);
  return(tail(mysvd$d, 1));
}

tt <- sum(.Internal(gc(FALSE, TRUE, TRUE))[13:14])
x <- smallest.sv()
sum(.Internal(gc(FALSE, FALSE, TRUE))[13:14]) - tt
#62 MB
rm(x)

Эта верхняя граница зависит от мусорасбор и, следовательно, включение gctorture даст нижнюю верхнюю границу :

tt <- sum(.Internal(gc(FALSE, TRUE, TRUE))[13:14])
gctorture(on = TRUE)
x <- smallest.sv()
gctorture(on = FALSE)
sum(.Internal(gc(FALSE, FALSE, TRUE))[13:14]) - tt
#53.7 MB

Другие инструменты, такие как Rprof, Rprofmem, profmem::profmem, bench::mark или profvis::profvis также может отображать использование памяти.

#Using Rprof (Enable profiling is a compile-time option: ./configure --enable_R_profiling)
gc()
Rprof("Rprof.out", memory.profiling=TRUE)
x <- smallest.sv()
Rprof(NULL)
max(summaryRprof("Rprof.out", memory="both")$by.total$mem.total)
#45.9
#Here at defined intervals the status is checked and so the result depends on if you hit the peak

#Using Rprofmem (Enable momory profiling is a compile-time option: ./configure --enable_memory_profiling)
Rprofmem("Rprofmem.out"); x <- smallest.sv(); Rprofmem(NULL) #Wen first run, there is much more in the log file
gc()
Rprofmem("Rprofmem.out")
x <- smallest.sv()
Rprofmem(NULL)
sum(as.numeric(read.table("Rprofmem.out", comment.char = ":")[,1]), na.rm=TRUE)
#88101752
#Writes out them memory amount when it is allocated

library(profmem) #uses utils::Rprofmem
gc()
total(profmem(x <- smallest.sv()))
#88101752

library(bench) #uses utils::Rprofmem
gc()
mark(x <- smallest.sv())[,"mem_alloc"]
#84MB
#Warning message:
#Some expressions had a GC in every iteration; so filtering is disabled. 

library(profvis) #uses utils::Rprof
gc()
profvis(x <- smallest.sv())
#opens a browser window where you can read under Memory -23.0 | 45.9

Rprofmem показывает память, которая была накоплена, и не учитывает память, которая была освобождена во время выполнения.Чтобы увеличить вероятность того, что Rprof достигнет пика, вы можете выбрать короткий интервал времени или / и повторить процедуру.

max(replicate(10, {
    gc()
    Rprof("Rprof.out", memory.profiling=TRUE, interval = runif(1,.005,0.02))
    x <- smallest.sv()
    Rprof(NULL)
    max(summaryRprof("Rprof.out", memory="both")$by.total$mem.total)
}))
#76.4

Здесь я получил более высокое значение, чем полученное из gc, чтодемонстрирует, что на использование памяти влияет сборка мусора и верхняя граница памяти , используемая во время обработки функции , может варьироваться от вызова к вызову, если gctorture не включен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...