Home Articles

doParallel,cluster vs cores

Asked
Viewed 1091 times
11

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

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

cl <- makeCluster(4)
registerDoParallel(cl)

registerDoParallel(cores = 4)

唯一的区别是我看到 makeCluster() 必须使用 stopCluster() 明确停止 .

3 Answers

  • 6

    doParallel::registerDoParallel(<numeric>) 的行为取决于操作系统,有关详细信息,请参阅 print(doParallel::registerDoParallel) .

    在Windows机器上,

    doParallel::registerDoParallel(4)
    

    有效的

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

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

    但是,在非Windows机器上,

    doParallel::registerDoParallel(4)
    

    结果将是 %dopar% 将使用 parallel::mclapply() 机器,而机械又依赖于分叉进程 . 由于使用了分叉,因此您不必担心全局变量和包 .

  • 4

    是的,从软件视图来看是正确的 .

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


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

    在硬件级别,'cluster'表示网络连接的机器,它们可以通过诸如插座之类的通信一起工作(需要更多的初始化/停止操作,如你所指出的那样) . 虽然'cores'表示本地CPU中的多个硬件核心,但它们通常由共享内存协同工作(不需要从A到B明确发送消息) .

    在软件级别,有时 clustercores 的边界并不清楚 . 该程序可以通过核心本地运行,也可以通过集群远程运行,高级软件不需要知道详细信息 . 因此,我们可以混合两种模式,例如在本地使用显式通信作为设置 cl 在一台机器中,并且还可以在每台远程机器中运行多核 .


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

    从软件中,程序将由相同数量的客户端/服务器运行,然后获得相同的结果 .

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

    But in practice, it is better to specify cores for single machine and cl for cluster.

    希望对您有所帮助 .

  • 1

    我认为所选择的答案过于笼统而且实际上并不准确,因为它没有触及 doParallel 包本身的细节 . 如果您阅读了小插曲,它实际上非常清楚 .

    并行软件包基本上是由Simon Urbanek编写的多核软件包和由Luke Tierney和其他人编写的雪包的合并 . 多核功能仅支持那些支持fork系统调用的操作系统上的多个worker;这不包括Windows . 默认情况下,doParallel在类Unix系统上使用多核功能,在Windows上使用snow功能 . 我们将在这个小插图中使用类似雪的功能,因此我们首先加载包并启动集群要使用类似多核的功能,我们将指定要使用的核心数量

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

    为了使接口一致,包对这两种模式使用相同的功能 .

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

Related