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 个“核心”(大概 2 个用于 foreach,2 个用于每个 mclapply。

4

1 回答 1

2

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

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

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

请注意,mclapply如果您使用 MPI 集群,它可能不会很好地发挥作用。MPI 不喜欢你像那样分叉进程mclapply。它可能只是发出一些严厉的警告,但我也看到了其他问题,所以我建议使用 PSOCK 集群,它使用 ssh 在远程节点上启动工作程序,而不是使用 MPI。


更新

mclapply从“parallel”和“snow”包创建的集群工作者调用似乎存在问题。有关更多信息,请参阅我对问题报告的回答

于 2016-01-12T14:56:45.087 回答