【发布时间】:2014-01-15 14:32:11
【问题描述】:
我正在尝试从串行方法转变为并行方法,以在大型 data.table 上完成一些多元时间序列分析任务。该表包含许多不同组的数据,我正在尝试使用doParallel 包从for 循环移动到foreach 循环,以利用安装的多核处理器。
我遇到的问题与内存以及新的 R 进程似乎如何消耗大量内存有关。我认为正在发生的事情是包含所有数据的大型 data.table 被复制到每个新进程中,因此我用完了 RAM,Windows 开始交换到磁盘。
我创建了一个简化的可重现示例,它复制了我的问题,但循环内的数据和分析更少。如果存在一种解决方案,该解决方案只能按需将数据外包给工作进程,或者在内核之间共享已经使用的内存,那将是理想的。或者,可能已经存在某种解决方案将大数据分成 4 个块并将它们传递给内核,以便它们有一个子集可以使用。
here on Stackoverflow 之前已经发布了一个类似的问题,但是我无法使用提供的bigmemory 解决方案,因为我的数据包含一个字符字段。我将进一步研究iterators 包,但我会感谢有此问题实践经验的成员提供的任何建议。
rm(list=ls())
library(data.table)
num.series = 40 # can customise the size of the problem (x10 eats my RAM)
num.periods = 200 # can customise the size of the problem (x10 eats my RAM)
dt.all = data.table(
grp = rep(1:num.series,each=num.periods),
pd = rep(1:num.periods, num.series),
y = rnorm(num.series * num.periods),
x1 = rnorm(num.series * num.periods),
x2 = rnorm(num.series * num.periods)
)
dt.all[,y_lag := c(NA, head(y, -1)), by = c("grp")]
f_lm = function(dt.sub, grp) {
my.model = lm("y ~ y_lag + x1 + x2 ", data = dt.sub)
coef = summary(my.model)$coefficients
data.table(grp, variable = rownames(coef), coef)
}
library(doParallel)
registerDoParallel(4)
foreach(grp=unique(dt.all$grp), .packages="data.table", .combine="rbind") %dopar%
{
dt.sub = dt.all[grp == grp]
f_lm(dt.sub, grp)
}
detach(package:doParallel)
【问题讨论】:
-
语句 dt.sub = dt.all[grp == grp] 将导致 dt.sub 的大量副本四处浮动。您是否尝试过在 lm 调用中使用 lm 的子集 = 参数来避免这样做?另外我想知道 f_lm 的返回值在计算时做了什么,它没有分配给任何东西。
-
是的,这个例子有缺陷。实际上,我必须缩小
stepAIC的上限和下限的可能公式,过滤掉NAs 的行,获得最佳模型,记录系数,计算弹性和样本内精度等。所以有除了运行lm之外还有几个步骤,我会尴尬地将data.tables的列表返回给foreach。我一定会给subset一些考虑,谢谢你的建议。我可以处理dt.sub的副本,只是dt.all在内存中不能有很多副本。 -
我很惊讶会创建 dt.all 的多个副本。根据多核的文档,“现代操作系统使用写时复制方法,这使得这对并行计算非常有吸引力,因为只有在计算期间修改的对象才会被实际复制,而所有其他内存都是直接共享的。”我知道 dt.all 在 Linux 上不会多次驻留在内存中。不确定 Windows。
-
doParallel: "多核功能仅在那些支持 fork 系统调用的操作系统上支持多个工作线程;这不包括 Windows。默认情况下,doParallel 在类 Unix 系统上使用多核功能,在 Windows 上使用雪功能”。我没有关于环境中的数据是否被复制的书面证据,但鉴于必须指定所需的包,并且我假设加载到 R 的每个实例中,那么数据也是必需的。我猜这是 Windows 的问题。
-
是的。有人告诉我这个功能在 Unix 上效果更好(因为 fork 命令),但切换可能不是你的选择。
标签: r memory foreach data.table