doParallel,集群与核心

Posted

技术标签:

【中文标题】doParallel,集群与核心【英文标题】:doParallel, cluster vs cores 【发布时间】:2015-05-03 22:57:18 【问题描述】:

使用doParallel包时registerDoParallel中的集群和核心有什么区别?

我的理解是否正确,在单机上这些是可以互换的,我会得到相同的结果:

cl <- makeCluster(4)
registerDoParallel(cl)    

registerDoParallel(cores = 4)

我看到的唯一区别是 makeCluster() 必须使用 stopCluster() 显式停止。

【问题讨论】:

不确定,但我猜你会受到核心数量的物理限制,但不受集群数量的限制,即“并行运行并通过套接字通信的 R 副本的数量”。当然,集群可能共享同一个内核,具体取决于集群数/内核数的比率。 我倾向于同意@Pascal 的观点,除了实际尝试可以实现的目标和工作方式之外,单台机器上没有任何区别。如果你只是想并行化一些代码,那么这两种方式都没有关系。 【参考方案1】:

我认为选择的答案过于笼统,实际上并不准确,因为它没有触及doParallel 包本身的细节。如果你读了这些小插曲,它实际上是很清楚的。

并行包本质上是多核的合并 包,由 Simon Urbanek 编写,还有雪包, 这是卢克蒂尔尼和其他人写的。多核 功能仅在那些操作的那些上支持多个工人 支持 fork 系统调用的系统;这不包括 Windows。经过 默认情况下,doParallel 在类 Unix 系统上使用多核功能 和 Windows 上的雪功能。

我们将在这个小插图中使用类似雪的功能,所以我们从 加载包并启动集群

要使用类似多核的功能,我们将指定 要使用的核心

总之,这取决于系统。集群是更通用的模式,覆盖所有平台,核心仅适用于类unix系统。

为使界面一致,包对这两种模式使用了相同的功能。

> library(doParallel)
> cl <- makeCluster(4)
> registerDoParallel(cl)
> getDoParName()
[1] "doParallelSNOW"

> registerDoParallel(cores=4)
> getDoParName()
[1] "doParallelMC"

【讨论】:

这应该被接受,因为它直接回答了OP的问题。【参考方案2】:

是的,就在软件视图中。

在单机上这些是可以互换的,我会得到相同的结果。


为了清楚地理解“集群”和“核心”,我建议从“硬件”和“软件”层面思考。

在硬件级别,“集群”是指网络连接的机器,它们可以通过诸如套接字之类的通信一起工作(需要更多的初始化/停止操作,正如您所指出的stopCluster)。而“核心”是指本地 CPU 中的多个硬件核心,它们通常通过共享内存一起工作(不需要从 A 显式发送消息到 B)。

在软件层面,有时clustercores 的界限并不那么清晰。程序可以通过核心在本地运行,也可以通过集群远程运行,高级软件不需要知道细节。因此,我们可以混合使用两种模式,例如在本地使用显式通信作为在一台机器上设置cl, 并且还可以在每台远程机器上运行多核。


回到你的问题,设置clcores 是否相等?

从软件来看,程序由相同数量的客户端/服务器运行,然后得到相同的结果。

从硬件上来说,可能会有所不同。 cl 表示显式通信,cores 表示共享内存,但如果高级软件优化得很好。在本地机器中,这两个设置将进入相同的流程。我现在对doParallel的研究不是很深,所以我不太确定这两个是否相同。

但实际上,最好为单机指定cores,为集群指定cl

希望对你有所帮助。

【讨论】:

这太笼统了。 OP的问题是关于 doParallel 包的具体问题,而不是一般概念问题。对于这个问题,更多的是关于平台实现,即使是单机也不一样。【参考方案3】:

doParallel::registerDoParallel(&lt;numeric&gt;) 的行为取决于操作系统,详情请参阅print(doParallel::registerDoParallel)

在 Windows 机器上,

doParallel::registerDoParallel(4)

有效

cl <- makeCluster(4)
doParallel::registerDoParallel(cl)

即它设置了四个(“PSOCK”)在后台 R 会话中运行的工作人员。然后,%dopar% 将基本上使用parallel::parLapply() 机器。使用这种设置,您必须担心全局变量和包会附加到每个工作人员上。

但是,在非 Windows 机器上,

doParallel::registerDoParallel(4)

结果将是%dopar% 将利用parallel::mclapply() 机制,而后者又依赖于分叉 进程。由于使用了分叉,因此您不必担心全局和包。

【讨论】:

要清楚,为什么 doParallel::registerDoParallel(4) 在 unix-likes 上与 cl &lt;- makeCluster(4, type = "FORK"); registerDoParallel(cl) 不一样?在我看来,这些应该是相同的,但在我的用例中后者要慢得多。 如果你遵循代码,你会看到doParallel::registerDoParallel() 在Unix 上最终会使用doParallel:::doParallelMC(),它使用parallel::mclapply() 进行处理。相比之下,使用makeCluster(4, type = "FORK"),或等效地,parallel::makeForkCluster() 设置了一个由分叉工作人员组成的 PSOCK 集群。当您将其传递给doParallel::registerDoParallel() 时,您最终将使用doParallel:::doParallelSNOW(),它依赖于parallel::clusterApplyLB() 进行处理。所以,它是parallel::mclapply()parallel::clusterApplyLB()

以上是关于doParallel,集群与核心的主要内容,如果未能解决你的问题,请参考以下文章

使用并行或 doParallel 为多个操作系统作为 CRAN 包的自定义包

“注销” doParallel 集群

R中doMC和doParallel的区别

R:在doParallel /降雪中制作集群挂起

插入符号训练二进制 glm 通过 doParallel 在并行集群上失败

已注册的 doParallel 集群不适用于 train/caret parRF 模型