【问题标题】:R bigmemory always use backing file?R bigmemory 总是使用支持文件?
【发布时间】:2018-01-27 08:08:30
【问题描述】:

我们正在尝试使用带有 foreach 的 BigMemory 库来并行我们的分析。但是, as.big.matrix 函数似乎总是使用 backingfile。我们的工作站有足够的内存,有没有办法在没有备份文件的情况下使用 bigMemory?

此代码x.big.desc <-describe(as.big.matrix(x)) 非常慢,因为它将数据写入C:\ProgramData\boost_interprocess\。不知何故比直接保存 x 慢,是 as.big.matrix 的 I/O 比较慢吗?

此代码x.big.desc <-describe(as.big.matrix(x, backingfile = "")) 非常快,但是,它也会将数据的副本保存到 %TMP% 目录。我们认为它之所以快,是因为 R 启动了一个后台写入过程,而不是实际写入数据。 (R提示返回后我们可以在TaskManager中看到写线程)。

有没有办法只使用带有 RAM 的 BigMemory,以便 foreach 循环中的每个工作人员都可以通过 RAM 访问数据?

感谢您的帮助。

【问题讨论】:

  • 从小插图来看,似乎不需要文件备份:数据结构可以分配到共享内存,允许同一台计算机上的不同进程共享对单个副本的访问的数据集。数据结构也可以支持填充,允许用户轻松管理和分析大于可用 RAM 的数据集,并在集群的节点之间共享它们。
  • 您可以通过指定shared = FALSE 在RAM 中使用big.matrix。但是,它不会在进程之间共享,因此您应该改用标准矩阵,将其复制到每个集群。存储在磁盘上的数据有什么问题?
  • lmo:虽然文档说备份文件不是必需的,但实际上它总是使用它。 Prive:如果 Shared = FALSE,我们不能使用 foreach 并行处理,worker 将无法访问数据。使用磁盘很慢,我们的数据很大,但我们有很大的 RAM,如果我们只能使用 RAM,我们会尽量避免从磁盘加载数据。
  • 如果你有足够的内存,为什么不使用标准的 R 矩阵呢?
  • @F.Privé 我们想用foreach来并行分析,但是将位矩阵传递给每个worker很慢,所以我们要使用bigMemory,所以每个work只复制它需要的列.此外,我们有足够的内存来存储数据,但如果我们有 20 个工作并且每个工作人员都获得数据的副本,那么内存就不够了。感谢您的回复。

标签: r r-bigmemory rparallel


【解决方案1】:

因此,如果您有足够的 RAM,只需使用标准 R 矩阵即可。要仅将每个矩阵的一部分传递给每个集群,请使用 rdsfiles。

一个使用 3 核计算 colSums 的示例:

# 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()

【讨论】:

  • Prive,这正是我们目前的方法。如果我们可以使用 BigMemory 来保存数据,并且让每个工作人员复制它需要的数据块,而不是写入/读取 RDS 文件,那就更好了。如果 BigMemory 可以用作共享内存,那么 foreach 工作可以从那里复制数据,那将会很有用。谢谢。
猜你喜欢
  • 2011-06-27
  • 2013-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-09
  • 2012-05-09
  • 1970-01-01
  • 2012-09-13
相关资源
最近更新 更多