同时使用foreach和mclapply实现R语言的并行化

4

我正在实现一个并行处理系统,最终将部署在集群上,但我在解决各种并行处理方法之间的交互时遇到了问题。

我需要使用for循环来运行一大块代码,其中包含几个大型矩阵操作列表。为了加速这个过程,我想用foreach()并行化for循环,并用mclapply并行化列表操作。

示例伪代码:

cl<-makeCluster(2)
registerDoParallel(cl)

outputs <- foreach(k = 1:2, .packages = "various packages") {

    l_output1 <- mclapply(l_input1, function, mc.cores = 2)
    l_output2 <- mclapply(l_input2, function, mc.cores = 2)
    return = mapply(cbind, l_output1, l_output2, SIMPLIFY=FALSE)
}

这看起来是可行的。我的问题是:

1)这是一个合理的方法吗?在小规模测试中,它们似乎能够一起工作,但感觉有点不稳定。

2)每次会使用多少个核心/处理器?当我将其升级为集群时,我需要了解可以推动到什么程度(foreach 每次循环只有7次,但 mclapply 列表里有70个左右大矩阵)。按照现有代码,它似乎创建了6个“核心”(可能是 foreach 用了2个,每个 mclapply 用了2个)。

1个回答

2
我认为在集群上这是一个非常合理的方法,因为它允许您同时使用多个节点,同时仍然可以跨各个节点的核心使用更高效的mclapply。此外,它还允许您在工作进程中进行一些后处理(在这种情况下调用cbind),这可以显著提高性能。
在单台机器上,您的示例将创建总共10个附加进程:两个由makeCluster创建,每个都调用mclapply两次(2 + 2(2 + 2))。但是,其中只有四个进程应该在任何时候使用大量CPU时间。您可以通过重构mclapply调用的函数来将其减少到八个进程,以便您只需要在foreach循环中调用一次mclapply,这可能更有效率。
在多台机器上,您将创建相同数量的进程,但每个节点每次只会使用两个进程。由于它们分布在多个机器上,因此应该具有良好的可伸缩性。
请注意,如果您使用MPI集群,则mclapply可能不会很好地运行。 MPI不希望您分叉进程,而mclapply会这样做。它可能只会发出一些严厉的警告,但我也见过其他问题,因此建议使用PSOCK集群,该集群使用ssh在远程节点上启动工作进程,而不是使用MPI。
更新
看起来使用“parallel”和“snow”包创建的集群工作者调用“mclapply”存在问题。有关更多信息,请参见我的问题报告的答案

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接