mclapply 使用所有内核但不是所有线程

Posted

技术标签:

【中文标题】mclapply 使用所有内核但不是所有线程【英文标题】:mclapply using all cores but not all threads 【发布时间】:2020-09-03 18:06:26 【问题描述】:

我有一台带有 8 个线程的 4 核 Mac。我对mclapply() 的理解是它应该利用 8 个线程作为处理器,但是当我运行我的脚本时,我只看到 4 个线程在工作。在我的示例中,我使用的是嵌套列表,因为在我的实际工作中,我有一个需要几天才能运行的 6 层嵌套列表。我将在 24 核 Linux 上运行我的脚本,因此我试图了解如何最好地利用我的资源。

library(zoo)

x = replicate(150000, rnorm(24)) 
list1 <- list(elem1 <- x, elem2 <- x)
nested_list <- list(elem1 = list1, elem2 = list1)

mclapply(nested_list, FUN = function(x)
  lapply(x, FUN = function(y)
    rollmean(y, 7)
  )
)

当我在运行这个脚本时监控我的 CPU 时,我看到了这个;

偶数核心似乎根本不工作,而核心 1 似乎有能力做更多事情。

mclapply() 不像 lapply() 的直接替代品那么简单吗?我使用的实际功能来自我需要使用的特定包,因此我无法更改功能以提高效率(即使用dplyr 功能而不是base 功能)。请告知我如何更有效地利用资源。

【问题讨论】:

【参考方案1】:

mclapply 和 fork 通常会受到内存的限制吗?我有一个在 24 核 Linux 上运行的脚本。在脚本的开头,mclapply(, mc.cores = 18) 使用了 18 个内核。脚本进行到一半时,在工作空间变得非常大(~3.5 GB)后,使用mclapply(, mc.cores = 18) 时只有 2 个内核可以工作。

我清理了内存,这改进了分叉。我尝试了mclapply(, mc.cores = 18),但通过监控我的内核的 CPU 使用率,我发现仍然只有 8 或 9 个内核在工作。我想知道这是否仍然是由于分叉所需的内存。我的理解是,在分叉时,会为每个分叉创建一个新的 R 会话。然后,这些会话中的每一个都需要加载工作区/库,这对于大量分叉来说可能是非常占用内存的。在处理大数据时有什么方法可以避免这种内存限制,从而更好地并行化?

这是我用来清理内存的代码;

# Clear plots
if(!is.null(dev.list())) dev.off()
# Clear console
cat("\014") 
# Clean workspace
rm(list=ls())

每http://www.sthda.com/english/articles/17-tips-tricks/75-clear-user-interface-and-free-memory-in-rrstudio/

【讨论】:

以上是关于mclapply 使用所有内核但不是所有线程的主要内容,如果未能解决你的问题,请参考以下文章

使用所有可用的内核和 CPU 是不是不负责任?

如何确认多核系统中的openmp是不是使用了所有内核?

为啥使用任务集在一组独立的内核上运行多线程 Linux 程序会导致所有线程在一个内核上运行?

OpenJDK为什么采用JVM线程和内核线程1:1的模型?

SylixOS 下内核线程简介

内核:如何从进程的 task_struct 中找到所有线程?