【问题标题】:Parallel processing in R done wrong?R中的并行处理做错了吗?
【发布时间】:2016-07-12 13:00:07
【问题描述】:

我有一个代码,我正在尝试使用 foreach 包并行处理。代码可以运行,但是当我在 4 核的计算机上运行它时,大约需要 26 分钟,当我切换到 32 核的计算机时,仍然需要 13 分钟才能完成。我想知道我是否做错了什么,因为我使用了 8 倍的内核,但只减少了一半的时间。我的代码如下所示:

no_cores <- detectCores()
cl <- makeCluster(no_cores)
registerDoParallel(cl)
Xenopus_Data <- foreach(b=1:length(newly_populated_vec),.packages = c("raster", "gdistance", "rgdal","sp")) %dopar% { Xenopus_Walk(altdata=altdata,water=water,habitat_suitability=habitat_suitability,max_range_without_water=max_range_without_water,max_range=max_range,slope=slope,Start_Pt=newly_populated_vec[b]) }
stopCluster(cl)  

对于具有 4 核的计算机,我得到以下时间:

Time_of_Start
[1] "2016-07-12 13:07:23 CEST"
Time_of_end
[1] "2016-07-12 13:33:10 CEST"

And for the one with 32 cores:
Time_of_Start
[1] "2016-07-12 14:35:48 CEST"
Time_of_end
[1] "2016-07-12 14:48:08 CEST"

这正常吗?如果是这样,有没有人知道如何加速它,也许使用不同的包? 非常感谢任何类型的帮助!

编辑:这些是我按照建议应用更正后得到的时间。对于 32 核:

User      System     elapsed 
5.99       40.78      243.97

4 核:

user  system  elapsed 
  1.91    0.94  991.71 

请注意,我之前通过一些循环进行了多次计算,这就是为什么计算时间大幅减少的原因,但我相信仍然可以看出两台计算机之间的差异有所增加。

【问题讨论】:

  • 如果不知道数据的大小与计算的复杂性相比,很难说时间是否合理。
  • 感谢您的回复。是的,我认为这对于任何试图回答这个问题的人来说可能都是一个问题,但是计算是基于我自己编写的一个相当复杂的函数,所以我认为如果我发布它,任何人都不会真正解决它。无论如何,数据也很大,因为该功能需要几个栅格层。你对我的最后一个问题有任何经验吗(是否有比 foreach 更快的包,如果 foreach 通常是一个很好的并行处理包)?我对这个问题很陌生......
  • 首先,尝试检查getDoParWorkers() 的注册核心数,看看一切正常。 (在foreach 之前)
  • @m0h3n,感谢您的提示。尽管getDoParWorkers() 返回的数字等于我可以使用的内核数量,但这是一个有用的功能,我将从现在开始使用它来检查一切是否正常。还不知道。

标签: r foreach parallel-foreach


【解决方案1】:

试试这个,如果您的问题得到解决,请告诉我:

library(doParallel)
library(foreach)
registerDoParallel(cores=detectCores())
n <- length(newly_populated_vec)
cat("\nN = ", n, " | Parallel workers count = ", getDoParWorkers(), "\n\n", sep="")

t0 <- proc.time()
Xenopus_Data <- foreach(b=1:n,.packages = c("raster", "gdistance", "rgdal","sp"), .combine=rbind) %dopar% { 
        Xenopus_Walk(
        water=water,
        altdata=altdata,
        habitat_suitability=habitat_suitability,
        max_range_without_water=max_range_without_water,
        max_range=max_range,
        slope=slope,
        Start_Pt=newly_populated_vec[b]) 
}
TIME <- proc.time() - t0

另外,请尝试监控您的 PC/笔记本电脑中的逻辑内核,以检查是否所有内核都参与了计算。 (Windows 的 TaskManager 和 Linux 的 htop

还请注意,核心数量翻倍并不一定会导致性能翻倍。

【讨论】:

  • 成功了,谢谢。你能告诉我我们两种方法之间的区别是什么,这样我就可以理解为什么你的方法效果更好?我将在上面的问题中编辑新时间。
  • @snoops 使用registerDoParallel() 负责注册和停止集群。此外,.combine=rbind 用于合并并行线程的结果。此外,在 foreach 循环之前和之后使用该时间,您可以更准确地捕捉并行工作所需的时间。
猜你喜欢
  • 2013-01-27
  • 1970-01-01
  • 1970-01-01
  • 2021-06-04
  • 2016-01-03
  • 2016-10-08
  • 1970-01-01
  • 2014-01-03
相关资源
最近更新 更多