与foreach和mclapply同时并行的r

时间:2016-01-10 11:16:08

标签: r foreach parallel-processing mclapply

我正在实现一个最终将部署在集群上的并行处理系统,但是我在弄清楚各种并行处理方法如何交互时遇到了麻烦。

我需要使用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&#34;核心&#34;正如所写的那样(大概是2为foreach,2为每个mclapply。

1 个答案:

答案 0 :(得分:2)

我认为这对群集来说是一种非常合理的方法,因为它允许您使用多个节点,同时仍然在各个节点的核心中使用效率更高的mclapply。它还允许您对工作人员进行一些后处理(在这种情况下调用cbind),这可以显着提高性能。

在一台计算机上,您的示例将创建总共10个额外的进程:两个makeCluster,每个进程调用mclapply两次(2 + 2(2 + 2))。但是,它们中只有四个应该一次使用任何重要的CPU时间。您可以通过重构mclapply调用的函数将其减少到八个进程,这样您只需要在foreach循环中调用mclapply一次,这可能会更有效。

在多台计算机上,您将创建相同数量的进程,但每个节点只有两个进程一次将占用大量CPU时间。由于它们分布在多台机器上,因此可以很好地扩展。

请注意,如果您使用MPI群集,mclapply可能无法正常播放。正如mclapply所做的那样,MPI不喜欢你分叉进程。它可能只是发出一些严厉的警告,但我也看到了other problems,所以我建议使用PSOCK集群,它使用ssh在远程节点上启动worker,而不是使用MPI。

更新

从“并行”和“雪”包创建的集群工作者调用mclapply似乎存在问题。有关详细信息,请参阅我的answer to a problem report