【发布时间】:2011-12-21 05:58:24
【问题描述】:
我正在使用 doSMP 包中的嵌套 foreach 来根据我开发的函数生成结果。通常问题会使用三个嵌套循环,但是由于生成的结果的大小(每个 i 大约 80,000 个),当最终结果矩阵超过指定的行数时,我不得不暂停编译并将结果写入文件。
i = 1
write.off = 1
while(i <= length(i.vector)){
results.frame = as.data.frame(matrix(NA, ncol = 3, nrow = 1))
while(nrow(results.frame) < 500000 & i <= length(i.vector)){
results = foreach(j = 1:length(j.vector), .combine = "rbind", .inorder = TRUE) %:%
foreach(k = 1:length(k.vector), .combine = "rbind", .inorder = TRUE) %dopar%{
ith.value = i.vector[i]
jth.value = j.vector[j]
kth.value = k.vector[k]
my.function(ith.value, jth.value, kth.value)
}
results.frame = rbind(results.frame, results)
i = i + 1
}
results.frame = results.frame[-1,]
write.table(results.frame, paste("part_",write.off, sep = ""))
write.off = write.off + 1
}
我遇到的问题是垃圾收集。工作人员似乎没有将内存重新分配回系统,因此在 i = 4 时,他们每个人都消耗了大约 6GB 的内存。
我尝试将 gc() 直接插入到 foreach 循环以及底层函数中,并且我还尝试将函数及其结果分配给我可以定期清除的命名环境。这些方法都没有奏效。
我觉得 foreach 的 initEnvir 和 finalEnvir 参数可能会提供一个解决方案,但文档和示例并没有真正说明这一点。
我在运行 Windows Server 2008 的 VM 上运行此代码。
【问题讨论】:
-
如果您知道要填充多少行(即长度(i.vector)),您可以通过设置 results.frame 一次来节省大量时间和内存。每次通过做 rbind 或其他事情需要大量的 cpu 工作。看看矢量化更好。另外:你真的应该使用
<-而不是=。相信我们:-) -
我还要指出,由于外循环是
i <= length(i.vector),因此在内循环中没有使用相同的条件。花点时间弄清楚你真正想在这里做什么。 -
外部 while 循环是为了让代码一直运行,直到它碰到 i.vector 中的最后一个元素(超过 1.8M)。第二个循环的原因是中断计算并定期保存结果。第二个 while 循环中的 i
-
我有同样的问题,有时我不得不杀死我所有的 R 进程,因为它们正在吃服务器 RAM (512 Gb)。
标签: r garbage-collection parallel-processing