【发布时间】:2018-12-11 18:08:11
【问题描述】:
我有一个foreach 循环,可以在大型数据集上并行一些计算。每个工作人员将其输出写入文件并将 NULL 返回给父进程。
出于这个原因,foreach 循环使用了一个虚拟组合器,它简单地忽略了工人的所有输出。奇怪的是,这适用于中小型数据帧,但不适用于大型数据帧。
具体来说,我的 data.table,比如 dt,由 7'237'605 行和 5'993 个唯一 ID 组成。每个工作人员都应该获取一个 id 并使用其对应的数据做某事。
实际循环如下:
unique_ids = unique(dt$id)
registerDoMC(40)
foreach(i=unique_ids,
.options.multicore=list(preschedule=TRUE),
.export=c('cfun'),
.combine='cfun', .multicombine=TRUE, .maxcombine = 3000,
.inorder=FALSE, .verbose = TRUE) %dopar%
{
DT = dt[id==i]
# do something with DT and write output to file
# ...
# ...
# finished writing to file
0 # return 0 or NULL, doesn't really matter, we don't care
}
combiner 函数忽略所有内容(取自 foreach 小插图):
cfun = function(...) {NULL}
归根结底,我只关心每个工作人员输出的文件。
如前所述,这适用于较小的数据集,例如 4'009'012 行和 5'993 唯一 ID。 .verbose 的输出符合预期:
numValues: 4993, numResults: 0, stopped: TRUE
setting mc.preschedule option to 1
然后在所有任务完成后:
got results for task 1
numValues: 4993, numResults: 1, stopped: TRUE
returning status FALSE
got results for task 2
numValues: 4993, numResults: 2, stopped: TRUE
returning status FALSE
...
got results for task 4993
numValues: 4993, numResults: 4993, stopped: TRUE
returning status FALSE
evaluating call object to combine results:
fun(accum, result.3001, result.3002, ... result.4993)
returning status TRUE
这几乎是瞬间发生的,因此在所有工作人员完成后我可以非常快速地控制主 R 进程(换句话说,组合结果没有成本)
但是对于大型 data.table,该过程会卡在:
numValues: 4993, numResults: 0, stopped: TRUE
setting mc.preschedule option to 1
即使任务完成后,也不会向父进程发送任何内容,也不会收集任何结果。
我该如何调试/纠正这个问题?
非常感谢。
【问题讨论】: