MrT*_*MrT 6 parallel-processing garbage-collection r
我正在使用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
}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是垃圾收集.工作人员似乎没有将内存重新分配给系统,所以i = 4他们每个人都吃掉了大约6GB的内存.
我已经尝试将gc()直接插入到foreach循环中以及底层函数中,并且我还尝试将函数及其结果分配给我可以定期清除的命名环境.这些方法都没有奏效.
我觉得foreach的initEnvir和finalEnvir参数可能提供了一个解决方案,但文档和示例并没有真正阐明这一点.
我在运行Windows Server 2008的VM上运行此代码.
您可以考虑通过编写不同的循环来完全避免此问题。
考虑使用gen.factorial中的函数AlgDesign,a:
fact1 = gen.factorial(c(length(i.vector), length(j.vector), length(k.vector)), nVars = 3, center = FALSE)
foreach(ix_row = 1:nrow(fact1)) %dopar% {
my.function(fact1[ix_row,])
}
Run Code Online (Sandbox Code Playgroud)
您还可以使用内存映射文件并使用(假设您正在创建矩阵)预先分配输出存储bigmemory,这将使每个工作人员可以自行存储其输出。
这样,您的整体内存使用量应该会大幅下降。
更新 1:内存问题似乎是doSMP. 查看以下帖子:
我记得看到另一个内存问题doSMP,无论是作为问题还是在 R 聊天中,但我似乎无法恢复该帖子。
更新2:我不知道这是否有帮助,但您可以尝试使用显式return()(例如return(my.function(ith.value, jth.value, kth.value)))。在我的代码中,为了清晰起见,我通常使用显式return()。