7

我编写了一些代码,使用foreach它处理和组合大量 CSV 文件。我在 32 核机器上运行它,使用%dopar%和注册 32 核doMC。我已经设置了.inorder=FALSE, .multicombine=TRUE, verbose=TRUE, 并且有一个自定义的组合功能。

我注意到,如果我在足够大的文件集上运行它,R 似乎会在第一次调用 .combine 之前尝试处理每个文件。我的证据是,在使用 htop 监视我的服务器时,我最初看到所有核心都已最大化,然后在剩余的工作中只使用一个或两个核心,而它以 ~100 的批次进行组合(.maxcombine默认值),如详细控制台输出所示。真正能说明问题的是,我为 foreach 提供的工作越多,看到“First call to combine”所需的时间就越长!

这对我来说似乎违反直觉。我天真地期望 foreach 处理.maxcombine文件,合并它们,然后继续下一批,将它们与最后一次调用的输出结合起来.combine。我想对于它的大多数用途.combine来说并不重要,因为输出的大小与输入大小的总和大致相同;但是我的组合功能稍微减小了大小。我的工作足够大,以至于我不可能同时在 RAM 中保存所有 4200 多个单独的 foreach 工作输出,所以我指望节省空间.combine和单独的批处理来帮助我完成任务。

在我所有的foreach工作都单独完成之前不会调用 .combine 是对的吗?如果是这样,为什么会这样,我该如何优化(除了使每个作业的输出更小)或改变这种行为?

4

1 回答 1

5

简短的回答是使用doMPIdoRedis作为您的并行后端。它们按您的预期工作得更多。

doMC,doSNOW和后端是对doParallel诸如mclapplyand之类的函数的相对简单的包装clusterApplyLB,并且在计算完所有结果之前不要调用 combine 函数,正如您所观察到的。, doMPI,doRedis和(现已失效)doSMP后端更复杂,并根据需要从迭代器获取输入并即时调用 combine 函数,正如您所假设的那样。在我看来,这些后端有很多优点,如果你有适当的迭代器和组合函数,它们可以让你处理任意数量的任务。令我感到惊讶的是,有这么多人与简单的后端相处得很好,但是如果你有很多任务,那么花哨的任务是必不可少的,它允许你做一些非常困难的事情,比如parallel.

我一直在考虑编写一个基于parallel包的更复杂的后端,它可以像我的doMPI包一样即时处理结果,但据我所知,还没有任何要求。事实上,你的问题是我见过的唯一此类问题。


更新

后端现在doSNOW支持即时结果处理。不幸的是,这无法完成,doParallel因为parallel包没有导出必要的功能。

于 2013-09-10T01:10:37.830 回答