同时将 r 与 foreach 和 mclapply 并行
parallel r with foreach and mclapply at the same time
我正在实现一个最终将部署在集群上的并行处理系统,但我无法弄清楚并行处理的各种方法如何交互。
我需要对 运行 一大段代码使用 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) 在任何给定时间它会使用多少 cores/processors?当我将它升级到一个集群时,我需要了解我可以将其推送多少(foreach 仅循环 7 次,但 mclapply 列表最多可达 70 个左右的大矩阵)。它似乎创建了 6 个 "cores"(大概是 foreach 2 个,每个 mclapply 2 个。
我认为在集群上这是一种非常合理的方法,因为它允许您使用多个节点,同时仍然在各个节点的核心上使用更高效的 mclapply
。它还允许您对工作人员执行一些 post-processing(在这种情况下调用 cbind
),这可以显着提高性能。
在一台机器上,您的示例将创建总共 10 个额外进程:两个 makeCluster
,每个调用 mclapply
两次 (2 + 2(2 + 2))。但是,他们中只有四个应该一次使用任何重要的 CPU 时间。您可以通过重构 mclapply
调用的函数将其减少到八个进程,这样您只需要在 foreach 循环中调用 mclapply
一次,这可能会更有效率。
在多台机器上,您将创建相同数量的进程,但每个节点只有两个进程一次会占用很多 CPU 时间。由于它们分布在多台机器上,因此应该可以很好地扩展。
请注意,如果您使用 MPI 集群,mclapply
可能无法正常播放。 MPI 不喜欢您像 mclapply
那样分叉进程。它可能只会发出一些严厉的警告,但我也看到了 other problems,所以我建议使用 PSOCK 集群,它使用 ssh 在远程节点上启动 worker,而不是使用 MPI。
更新
似乎从 "parallel" 和 "snow" 包创建的集群工作程序调用 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) 在任何给定时间它会使用多少 cores/processors?当我将它升级到一个集群时,我需要了解我可以将其推送多少(foreach 仅循环 7 次,但 mclapply 列表最多可达 70 个左右的大矩阵)。它似乎创建了 6 个 "cores"(大概是 foreach 2 个,每个 mclapply 2 个。
我认为在集群上这是一种非常合理的方法,因为它允许您使用多个节点,同时仍然在各个节点的核心上使用更高效的 mclapply
。它还允许您对工作人员执行一些 post-processing(在这种情况下调用 cbind
),这可以显着提高性能。
在一台机器上,您的示例将创建总共 10 个额外进程:两个 makeCluster
,每个调用 mclapply
两次 (2 + 2(2 + 2))。但是,他们中只有四个应该一次使用任何重要的 CPU 时间。您可以通过重构 mclapply
调用的函数将其减少到八个进程,这样您只需要在 foreach 循环中调用 mclapply
一次,这可能会更有效率。
在多台机器上,您将创建相同数量的进程,但每个节点只有两个进程一次会占用很多 CPU 时间。由于它们分布在多台机器上,因此应该可以很好地扩展。
请注意,如果您使用 MPI 集群,mclapply
可能无法正常播放。 MPI 不喜欢您像 mclapply
那样分叉进程。它可能只会发出一些严厉的警告,但我也看到了 other problems,所以我建议使用 PSOCK 集群,它使用 ssh 在远程节点上启动 worker,而不是使用 MPI。
更新
似乎从 "parallel" 和 "snow" 包创建的集群工作程序调用 mclapply
时出现问题。有关详细信息,请参阅我的