【问题标题】:Increasing mc.cores beyond the number of logical cores增加 mc.cores 超出逻辑核心数
【发布时间】:2020-04-09 06:49:01
【问题描述】:

玩弄 R 函数parallel::mclapply,我发现参数mc.cores 可以选择大于逻辑核心的数量(如parallel::detectCores 所示),从而导致加速大于逻辑核心的数量。这是一个最小的例子(对我来说,这适用于 MacOS 和 Linux):

sleepy <- function(i) {
    start <- Sys.time()
    Sys.sleep(i)
    as.numeric(Sys.time() - start)
}

mc.cores <- 100L
ntasks   <- 10000L

start <- Sys.time()
out <- parallel::mclapply(2/ntasks*runif(ntasks), sleepy, mc.cores = mc.cores)

real_duration <- as.numeric(Sys.time() - start)
cpu_duration <- sum(unlist(out))

data.frame(logical.cores = parallel::detectCores(),
           mc.cores      = mc.cores,
           speedup       = cpu_duration/real_duration)


##   logical.cores mc.cores  speedup
## 1             8      100 30.49574

我还在一个更现实的例子中进行了尝试,即接近我想要并行化的真实场景:这也没有导致任何问题。

parallel::mclapply 的/tutorials 文档中,我找不到任何选择mc.cores &gt; detectCores() 的示例,而且很可能有一个很好的理由。

有人能解释一下这种做法有什么问题吗?在某些情况下是否合理,例如当内存要求不是问题时?

【问题讨论】:

  • 什么是parallel::detectCores(logical = FALSE)

标签: r parallel-processing mclapply


【解决方案1】:

我有时使用mc.cores &gt; detectCores() 来限制内存使用。如果你将一个作业分成 10 个部分并用mclapplymc.preschedule=F 处理它们,每个内核一次只能处理你作业的 10%。例如,如果mc.cores 设置为两个,那么其他 8 个“节点”必须等到一个部分完成后才能开始新的一个。如果您遇到内存问题并希望防止每个循环超出其处理能力,这可能是可取的。

【讨论】:

    【解决方案2】:

    它所做的只是产生线程,您可以将它们视为具有共享内存的轻量级进程。通常,由于上下文切换开销,生成比可用内核更多的线程并不是最佳选择。根据经验,大多数情况下,工作人员的数量最好等于 CPU 的逻辑核心数量。

    【讨论】:

    • 这不是真的。人们通常建议为操作系统保留至少一个内核,或仅使用物理内核。
    猜你喜欢
    • 1970-01-01
    • 2014-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-11
    • 2013-07-04
    • 2011-09-12
    • 1970-01-01
    相关资源
    最近更新 更多