简体   繁体   English

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

[英]Whether to use the detectCores function in R to specify the number of cores for parallel processing?

In the help for detectCores() it says:detectCores()帮助中,它说:

This is not suitable for use directly for the mc.cores argument of mclapply nor specifying the number of cores in makeCluster .这不适合直接用于 mclapply 的 mc.cores 参数,也不适合指定makeCluster 中的核心数 First because it may return NA, and second because it does not give the number of allowed cores.首先是因为它可能返回 NA,其次是因为它没有给出允许的内核数。

However, I've seen quite a bit of sample code like the following:但是,我已经看到了很多示例代码,如下所示:

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)

where detectCores() is used to specify the number of cores in makeCluster .其中detectCores()用于指定makeCluster的核心makeCluster

My use cases involve running parallel processing both on my own multicore laptop (OSX) and running it on various multicore servers (Linux).我的用例涉及在我自己的多核笔记本电脑 (OSX) 和各种多核服务器 (Linux) 上运行并行处理。 So, I wasn't sure whether there is a better way to specify the number of cores or whether perhaps that advice about not using detectCores was more for package developers where code is meant to run over a wide range of hardware and OS environments.因此,我不确定是否有更好的方法来指定内核的数量,或者关于不使用detectCores建议是否更适用于代码要在广泛的硬件和操作系统环境中运行的包开发人员。

So in summary:所以总结一下:

  • Should you use the detectCores function in R to specify the number of cores for parallel processing?你应该使用 R 中的detectCores函数来指定并行处理的核心数吗?
  • What is the distinction mean between detected and allowed cores and when is it relevant?检测到的内核和允许的内核之间的区别是什么意思,何时相关?

I think it's perfectly reasonable to use detectCores as a starting point for the number of workers/processes when calling mclapply or makeCluster .我认为在调用mclapplymakeCluster时使用detectCores作为工作人员/进程数量的起点是完全合理的。 However, there are many reasons that you may want or need to start fewer workers, and even some cases where you can reasonably start more.但是,您可能希望或需要启动更少的工人的原因有很多,甚至在某些情况下您可以合理地启动更多。

On some hyperthreaded machines it may not be a good idea to set mc.cores=detectCores() , for example.例如,在某些超线程机器上设置mc.cores=detectCores()可能不是一个好主意。 Or if your script is running on an HPC cluster, you shouldn't use any more resources than the job scheduler has allocated to your job.或者,如果您的脚本在 HPC 集群上运行,则不应使用比作业调度程序分配给您的作业更多的资源。 You also have to be careful in nested parallel situations, as when your code may be executed in parallel by a calling function, or you're executing a multithreaded function in parallel.在嵌套并行情况下,您还必须小心,因为当您的代码可能由调用函数并行执行时,或者您正在并行执行多线程函数时。 In general, it's a good idea to run some preliminary benchmarks before starting a long job to determine the best number of workers.通常,在开始长期工作之前运行一些初步基准测试以确定最佳工人数量是一个好主意。 I usually monitor the benchmark with top to see if the number of processes and threads makes sense, and to verify that the memory usage is reasonable.我通常使用top监控基准测试,看看进程和线程的数量是否合理,并验证内存使用是否合理。

The advice that you quoted is particularly appropriate for package developers.您引用的建议特别适合包开发人员。 It's certainly a bad idea for a package developer to always start detectCores() workers when calling mclapply or makeCluster , so it's best to leave the decision up to the end user.对于包开发人员来说,在调用mclapplymakeCluster时总是启动detectCores()工作人员当然是一个坏主意,因此最好将决定权留给最终用户。 At least the package should allow the user to specify the number of workers to start, but arguably detectCores() isn't even a good default value.至少该包应该允许用户指定要启动的工人数量,但可以说detectCores()甚至不是一个好的默认值。 That's why the default value for mc.cores changed from detectCores() to getOptions("mc.cores", 2L) when mclapply was included in the parallel package.这就是为什么默认值mc.cores从改变detectCores()getOptions("mc.cores", 2L)mclapply被列入parallel包。

I think the real point of the warning that you quoted is that R functions should not assume that they own the whole machine, or that they are the only function in your script that is using multiple cores.我认为您引用的警告的真正要点是 R 函数不应该假设它们拥有整台机器,或者它们是脚本中使用多核的唯一函数。 If you call mclapply with mc.cores=detectCores() in a package that you submit to CRAN, I expect your package will be rejected until you change it.如果您在提交给 CRAN 的包中使用mc.cores=detectCores()调用mclapply ,我希望您的包将被拒绝,直到您更改它。 But if you're the end user, running a parallel script on your own machine, then it's up to you to decide how many cores the script is allowed to use.但是,如果您是最终用户,在自己的机器上运行并行脚本,则由您决定允许脚本使用多少个内核。

Author of the parallelly package here: The parallelly::availableCores() function acknowledges various HPC environment variables (eg NSLOTS , PBS_NUM_PPN , and SLURM_CPUS_PER_TASK ) and system and R settings that are used to specify the number of cores available to the process, and if not specified, it'll fall back to parallel::detectCores() .此处并行包的作者: parallelly::availableCores()函数确认各种 HPC 环境变量(例如NSLOTSPBS_NUM_PPNSLURM_CPUS_PER_TASK )以及用于指定进程可用内核数的系统和 R 设置,以及如果未指定,它将回退到parallel::detectCores() As I, or others, become aware of more settings, I'll be happy to add automatic support also for those;当我或其他人了解更多设置时,我很乐意为这些设置添加自动支持; there is an always open GitHub issue for this over at https://github.com/HenrikBengtsson/parallelly/issues/17 (there are some open requests for help).https://github.com/HenrikBengtsson/parallelly/issues/17上有一个始终未解决的 GitHub 问题(有一些开放的帮助请求)。

Also, if the sysadm sets environment variable R_PARALLELLY_AVAILABLECORES_FALLBACK=1 sitewide, then parallelly::availableCores() will return 1, unless explicitly overridden by other means (by the job scheduler, by the user settings, ...).此外,如果 sysadm 在站点范围内设置环境变量R_PARALLELLY_AVAILABLECORES_FALLBACK=1 ,则parallelly::availableCores()将返回 1,除非被其他方式(作业调度程序、用户设置等)显式覆盖。 This further protects against software tools taking over all cores by default.这进一步防止软件工具在默认情况下接管所有内核。

In other words, if you use parallelly::availableCores() rather than parallel::detectCores() you can be fairly sure that your code plays nice in multi-tenant environments (if it turns out it's not enough, please let us know in the above GitHub issue) and that any end user can still control the number of cores without you having to change your code.换句话说,如果您使用parallelly::availableCores()而不是parallel::detectCores()您可以相当确定您的代码在多租户环境中运行良好(如果事实证明这还不够,请让我们知道上述 GitHub 问题),并且任何最终用户仍然可以控制内核数量,而无需更改代码。

EDIT 2021-07-26: availableCores() was moved from future to parallelly in October 2020. For now and for backward compatible reasons, availableCores() function is re-exported by the 'future' package.编辑 2021-07-26: availableCores()在 2020 年 10 月从未来移动到并行。出于现在和向后兼容的原因, availableCores()函数由“future”包重新导出。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM