问题 是否使用R中的detectCores函数指定并行处理的核心数?


在里面 帮帮我 对于 detectCores() 它说:

这不适合 直接用于mc.cores参数   mclapply也不是 指定makeCluster中的核心数。第一   因为它可能会返回NA,其次是因为它没有给出   允许的核心数量。

但是,我已经看到了相当多的示例代码,如下所示:

library(parallel)
k <- 1000
m <- lapply(1:7, function(X) matrix(rnorm(k^2), nrow=k))

cl <- makeCluster(detectCores() - 1, type = "FORK")
test <- parLapply(cl, m, solve)
stopCluster(cl)

哪里 detectCores() 用于指定核心数量 makeCluster

我的用例包括在我自己的多核笔记本电脑(OSX)上运行并行处理并在各种多核服务器(Linux)上运行它。所以,我不确定是否有更好的方法来指定核心数量,或者是否有关于不使用的建议 detectCores 更适用于代码开发人员,其中代码可以在各种硬件和操作系统环境中运行。

总结如下:

  • 你应该使用 detectCores R中的函数指定并行处理的核心数?
  • 检测到的和允许的核心之间的区别是什么?它们何时相关?

5994
2018-03-10 02:06


起源

你在哪个平台上? system('getconf _NPROCESSORS_ONLN') - rawr
OSX和Linux;我已经更新了我的问题以说明这一点;虽然我想我对一般答案很感兴趣,但这对其他人有用。 - Jeromy Anglim


答案:


我觉得使用它是完全合理的 detectCores 作为呼叫时工人/进程数量的起点 mclapply 要么 makeCluster。但是,您可能需要或需要创建更少的工作人员的原因有很多,甚至有些情况下您可以合理地开始更多工作。

在一些超线程机器上,设置可能不是一个好主意 mc.cores=detectCores(), 例如。或者,如果您的脚本在HPC群集上运行,则不应使用比作业计划程序分配给您的作业更多的资源。您还必须在嵌套并行情况下小心,因为您的代码可能由调用函数并行执行,或者您并行执行多线程函数。一般来说,在开始长期工作之前运行一些初步基准以确定最佳工人数是个好主意。我经常监控基准测试 top 查看进程和线程的数量是否有意义,并验证内存使用是否合理。

您引用的建议特别适合包开发人员。对于软件包开发人员来说,始终是一个坏主意 detectCores() 工人打电话 mclapply 要么 makeCluster,所以最好将决定留给最终用户。至少包应该允许用户指定要启动的工人数量,但可以说 detectCores() 甚至不是一个很好的默认值。这就是为什么默认值 mc.cores 改变了 detectCores() 至 getOptions("mc.cores", 2L) 什么时候 mclapply 被包括在内 parallel 包。

我认为你引用的警告的真正意义在于R函数不应该假设它们拥有整个机器,或者它们是脚本中使用多个内核的唯一函数。如果你打电话 mclapply 同 mc.cores=detectCores() 在您提交给CRAN的软件包中,我希望您的软件包在您更改之前将被拒绝。但是,如果您是最终用户,在您自己的计算机上运行并行脚本,则由您决定允许脚本使用多少个核心。


14
2018-03-10 15:40



因此,如果我不拥有该机器,并且每个节点的核心数量少于可用,我该如何使用 detectCores() 或类似的东西,以确保我只使用允许的核心?在那种情况下,我应该手动把它? - Plinth
@Plinth在那种情况下, detectCores() 用处不大。如果您正在使用批处理排队系统,则通常可以使用环境变量来确定每个节点已分配给作业的核心数。在Torque上,您可以使用类似的方法计算$ PBS_NODEFILE中列出的节点名称 table(readLines(Sys.getenv('PBS_NODEFILE')))。但通常您可能必须将此信息指定为R脚本的命令行参数。 - Steve Weston
不想让我的事情太复杂化 future::availableCores() 回答,但是 future::availableWorkers() 解析已知的HPC文件,例如 PBS_NODEFILE 史蒂夫提到。我认为这应该只适用于多节点作业,我相信 PBS_NUM_PPN 总是设定(乐于纠正/另外学习)。 - HenrikB


在我的情况下更好(我使用mac)是 future::availableCores() 因为 detectCores() 显示160这显然是错误的。


1
2017-09-15 18:37





作者 未来 包这里: future::availableCores() 函数确认各种HPC环境变量(例如 NSLOTSPBS_NUM_PPN,和 SLURM_CPUS_PER_TASK)和系统和R设置,用于指定进程可用的核心数,如果没有指定,它将回退到 parallel::detectCores()。当我或其他人意识到更多设置时,我也很乐意为这些设置添加自动支持;有一个永远开放的GitHub问题 https://github.com/HenrikBengtsson/future/issues/22 (有一些公开的求助请求)。

此外,如果sysadm设置环境变量 R_FUTURE_AVAILABLECORES_FALLBACK=1 然后,整个网站 future::availableCores() 将返回1,除非通过其他方式显式覆盖(通过作业调度程序,通过用户设置,...)。这进一步防止了默认情况下接管所有核心的软件工具。

换句话说,如果你使用 future::availableCores() 而不是 parallel::detectCores() 您可以相当确定您的代码在多租户环境中运行良好(如果事实证明它还不够,请在上面的GitHub问题中告诉我们)并且任何最终用户仍然可以控制核心数量而无需改变你的代码。


1
2017-09-15 19:47