R bigmemory всегда использует резервный файл?

Мы пытаемся использовать библиотеку BigMemory с foreach для параллельного анализа. Однако функция as.big.matrix всегда использует резервный файл. На наших рабочих станциях достаточно памяти, есть ли способ использовать bigMemory без резервного файла?

Этот код x.big.desc <-describe(as.big.matrix(x)) работает довольно медленно, поскольку записывает данные в C:\ProgramData\boost_interprocess\. Почему-то это медленнее, чем непосредственное сохранение x, это as.big.matrix, у которого более медленный ввод-вывод?

Этот код x.big.desc <-describe(as.big.matrix(x, backingfile = "")) работает довольно быстро, однако он также сохраняет копию данных в каталоге %TMP%. Мы думаем, что причина в том, что это быстро, потому что R запускает фоновый процесс записи вместо фактической записи данных. (Мы можем увидеть поток записи в TaskManager после возврата приглашения R).

Есть ли способ использовать BigMemory только с оперативной памятью, чтобы каждый рабочий процесс в цикле foreach мог получить доступ к данным через оперативную память?

Спасибо за помощь.


person user7648269    schedule 18.08.2017    source источник
comment
Из виньетки видно, что резервное копирование файлов не требуется: Структуры данных могут размещаться в общей памяти, что позволяет отдельным процессам на одном компьютере совместно использовать доступ к одной копии набора данных. Структуры данных также могут быть заполнены, что позволяет пользователям легко управлять и анализировать наборы данных, объем которых превышает объем доступной оперативной памяти, и совместно использовать их между узлами кластера.   -  person lmo    schedule 18.08.2017
comment
Вы можете использовать big.matrix в ОЗУ, указав shared = FALSE. Однако она не будет разделена между процессами, поэтому вместо нее следует использовать стандартную матрицу, которая копируется в каждый кластер. В чем проблема с данными, хранящимися на диске?   -  person F. Privé    schedule 18.08.2017
comment
lmo: Хотя в документе сказано, что резервный файл не нужен, но на практике он всегда использовался. Prive: при Shared = FALSE мы не можем использовать параллельную обработку foreach, воркеры не смогут получить доступ к данным. Использование диска медленное, наши данные большие, но у нас большая оперативная память, мы стараемся избегать загрузки данных с дисков, если можем использовать только оперативную память.   -  person user7648269    schedule 18.08.2017
comment
Если у вас достаточно памяти, почему бы тогда не использовать стандартные R-матрицы?   -  person F. Privé    schedule 19.08.2017
comment
@F.Privé мы хотим использовать foreach для параллельного анализа, но передача битовой матрицы каждому рабочему процессу очень медленная, поэтому мы хотим использовать bigMemory, чтобы каждая работа копировала только тот столбец, который ей нужен. Также у нас достаточно памяти для данных, но недостаточно оперативной памяти, если у нас 20 работ и каждый воркер получает копию данных. Спасибо за ответ.   -  person user7648269    schedule 19.08.2017


Ответы (1)


Итак, если у вас достаточно оперативной памяти, просто используйте стандартные R-матрицы. Чтобы передать только часть каждой матрицы в каждый кластер, используйте rdsfiles.

Один пример вычисления colSums с 3 ядрами:

# Functions for splitting
CutBySize <- function(m, nb) {
  int <- m / nb

  upper <- round(1:nb * int)
  lower <- c(1, upper[-nb] + 1)
  size <- c(upper[1], diff(upper))

  cbind(lower, upper, size)
}
seq2 <- function(lims) seq(lims[1], lims[2])

# The matrix
bm <- matrix(1, 10e3, 1e3)
ncores <- 3
intervals <- CutBySize(ncol(bm), ncores)
# Save each part in a different file
tmpfile <- tempfile()
for (ic in seq_len(ncores)) {
  saveRDS(bm[, seq2(intervals[ic, ])], 
          paste0(tmpfile, ic, ".rds"))
}
# Parallel computation with reading one part at the beginning
cl <- parallel::makeCluster(ncores)
doParallel::registerDoParallel(cl)
library(foreach)
colsums <- foreach(ic = seq_len(ncores), .combine = 'c') %dopar% {
  bm.part <- readRDS(paste0(tmpfile, ic, ".rds"))
  colSums(bm.part)
}
parallel::stopCluster(cl)
# Checking results
all.equal(colsums, colSums(bm))

Вы даже можете использовать rm(bm); gc() после записи частей на диск.

person F. Privé    schedule 19.08.2017
comment
Prive, это именно наш нынешний метод. Было бы лучше, если бы мы могли использовать BigMemory для сохранения данных и чтобы каждый рабочий процесс копировал блок необходимых ему данных вместо записи/чтения файлов RDS. Было бы полезно, если бы BigMemory можно было использовать как shared-memory, чтобы foreach работал и мог копировать данные оттуда. Спасибо. - person user7648269; 21.08.2017