我正在实现一个最终将部署在集群上的并行处理系统,但是我在弄清楚各种并行处理方法如何交互时遇到了麻烦.
我需要使用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).
最佳答案 我认为这对集群来说是一种非常合理的方法,因为它允许您使用多个节点,同时仍然在各个节点的核心上使用更高效的mclapply.它还允许您对worker进行一些后处理(在这种情况下调用cbind),这可以显着提高性能.
在一台机器上,你的例子将创建总共10个额外的进程:两个由makeCluster创建,每个进程调用mclapply两次(2 2(2 2)).但是,它们中只有四个应该一次使用任何重要的CPU时间.您可以通过重构mclapply调用的函数将其减少到8个进程,这样您只需要在foreach循环中调用mclapply一次,这可能更有效.
在多台计算机上,您将创建相同数量的进程,但每个节点只有两个进程一次将占用大量CPU时间.由于它们分布在多台机器上,因此应该可以很好地扩展.
请注意,如果使用MPI群集,mclapply可能无法正常播放.正如mclapply所做的那样,MPI不喜欢你分叉进程.它可能只是发出一些严厉的警告,但我也看到了other problems,所以我建议使用PSOCK集群,它使用ssh在远程节点上启动工作而不是使用MPI.
更新
看起来从“并行”和“雪”包创建的集群工作者调用mclapply时出现问题.有关更多信息,请参阅我的answer to a problem report.