在detectCores()
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)
中,它说:
这不适合直接用于mc.cores参数 mclapply,指定makeCluster中的核心数。第一 因为它可能会返回NA,其次是因为它没有给出 允许的核心数量。
但是,我已经看到了相当多的示例代码,如下所示:
detectCores()
其中makeCluster
用于指定detectCores
中的核心数。
我的用例包括在我自己的多核笔记本电脑(OSX)上运行并行处理并在各种多核服务器(Linux)上运行它。所以,我不确定是否有更好的方法来指定内核数量,或者对于不使用detectCores
的建议是否更多适用于代码开发人员,其中代码可以运行在各种硬件上OS环境。
总结如下:
答案 0 :(得分:14)
我认为在调用detectCores
或mclapply
时,使用makeCluster
作为工作人员/流程数量的起点是完全合理的。但是,您可能需要或需要少量工作的原因有很多,甚至有些情况下您可以合理地开始工作。
在某些超线程计算机上,例如设置mc.cores=detectCores()
可能不是一个好主意。或者,如果您的脚本在HPC群集上运行,则不应使用比作业计划程序分配给您的作业更多的资源。您还必须在嵌套并行情况下小心,因为您的代码可能由调用函数并行执行,或者您并行执行多线程函数。一般来说,在开始长期工作以确定最佳工人数量之前,先运行一些初步基准是一个好主意。我通常使用top
监视基准测试,以查看进程和线程的数量是否合理,并验证内存使用是否合理。
您引用的建议特别适合包开发人员。对于软件包开发人员来说,在致电detectCores()
或mclapply
时始终启动makeCluster
工作人员当然是个坏主意,所以最好将决定权交给最终用户。至少包应该允许用户指定要开始的工人数量,但可以说detectCores()
甚至不是一个好的默认值。这就是mc.cores
包中包含detectCores()
时getOptions("mc.cores", 2L)
的默认值从mclapply
更改为parallel
的原因。
我认为你引用的警告的真正意义在于R函数不应该假设它们拥有整个机器,或者它们是脚本中使用多个核心的唯一函数。如果您在提交给CRAN的软件包中使用mclapply
拨打mc.cores=detectCores()
,我希望您的软件包在您更改之前将被拒绝。但是,如果您是最终用户,在您自己的计算机上运行并行脚本,那么您可以决定允许脚本使用多少个核心。
答案 1 :(得分:4)
future包的作者:future::availableCores()
函数确认各种HPC环境变量(例如NSLOTS
,PBS_NUM_PPN
和SLURM_CPUS_PER_TASK
)和系统R设置用于指定进程可用的核心数,如果未指定,则它将回退到parallel::detectCores()
。当我或其他人意识到更多设置时,我也很乐意为这些设置添加自动支持;在https://github.com/HenrikBengtsson/future/issues/22有一个永远公开的GitHub问题(有一些公开请求帮助)。
此外,如果sysadm在整个网站范围内设置环境变量R_FUTURE_AVAILABLECORES_FALLBACK=1
,则future::availableCores()
将返回1,除非通过其他方式(由作业调度程序,用户设置,...)显式覆盖。这进一步防止了默认情况下接管所有核心的软件工具。
换句话说,如果你使用future::availableCores()
而不是parallel::detectCores()
,你可以相当确定你的代码在多租户环境中表现得很好(如果事实证明它还不够,请在上面的GitHub问题中告诉我们)并且任何最终用户仍然可以控制核心数量,而无需更改代码。
答案 2 :(得分:1)
我的情况更好(我使用mac)是future::availableCores()
,因为detectCores()
显示160,这显然是错误的。