【问题标题】:Trying to get started with doParallel and foreach but no improvement尝试开始使用 doParallel 和 foreach 但没有改进
【发布时间】:2013-05-20 01:00:23
【问题描述】:

我正在尝试使用 doParallel 和 foreach 包,但使用此处CRANpage 中的指南中的引导示例会降低性能。

library(doParallel)
library(foreach)
registerDoParallel(3)
x <- iris[which(iris[,5] != "setosa"), c(1,5)]
trials <- 10000
ptime <- system.time({
  r <- foreach(icount(trials), .combine=cbind) %dopar% {
    ind <- sample(100, 100, replace=TRUE)
    result1 <- glm(x[ind,2]~x[ind,1], family=binomial(logit))
    coefficients(result1)
    }
  })[3]
ptime

此示例返回56.87

当我将dopar 更改为仅do 以按顺序而不是并行运行时,它会返回36.65

如果我执行registerDoParallel(6),它会将并行时间降低到42.11,但仍然比顺序慢。 registerDoParallel(8) 得到 40.31 仍然比顺序差。

如果我将 trials 增加到 100,000,则顺序运行需要 417.16,而具有 3 个工作人员的并行运行需要 597.31。有 6 个并行工作人员需要 425.85

我的系统是

  • 戴尔 Optiplex 990

  • Windows 7 Professional 64 位

  • 16GB 内存

  • Intel i-7-2600 3.6GHz 四核超线程

我在这里做错了吗?如果我做我能想到的最人为的事情(用Sys.sleep(1) 替换计算代码),那么我会得到与工人数量密切相关的实际减少。我想知道为什么指南中的示例会降低我的性能,而对他们来说却加快了速度?

【问题讨论】:

  • 这是一个几乎是常见问题解答:您使用 Sys.sleep() 进行测试很好,它表明设置线程需要比计算更多的时间。尝试增加问题的大小,即样本(10000),您会看到改进。但是,您的机器实际上只有 4 个内核,因此除了 4 个内核之外没有任何工作。我从未见过超线程的效果(在 Windows 下,并且没有特殊的 R 编译)
  • @DieterMenne:您关于这是常见问题的观点是正确的。事实上,指南的例子并没有通过我回来给我带来好处。你说得对,增加样本量会让我达到并行运行的改进。另外,感谢有关 HT 的提示。我做了一个 4 vs 8 工人的测试,基本上是同一时间。

标签: r parallel-processing mpi


【解决方案1】:

根本问题是doParallel 为 PSOCK 集群的工作人员上的每个任务执行执行 attach,以便将导出的变量添加到包搜索路径。这解决了各种范围界定问题,但可能会严重影响性能,尤其是在短期任务和大量导出数据的情况下。对于您的示例,这不会在 Linux 和 Mac OS X 上发生,因为它们将使用 mclapply,而不是 clusterApplyLB,但如果您显式注册 PSOCK 集群,它将在所有平台上发生.

我相信我已经想出了如何以不影响性能的不同方式解决任务范围界定问题,我正在与 Revolution Analytics 合作以将修复程序添加到 doParallel 的下一个版本中,并且doSNOW,也有同样的问题。

您可以通过使用任务分块来解决此问题:

ptime2 <- system.time({
  chunks <- getDoParWorkers()
  r <- foreach(n=idiv(trials, chunks=chunks), .combine='cbind') %dopar% {
    y <- lapply(seq_len(n), function(i) {
      ind <- sample(100, 100, replace=TRUE)
      result1 <- glm(x[ind,2]~x[ind,1], family=binomial(logit))
      coefficients(result1)
    })
    do.call('cbind', y)
  }
})[3]

这导致每个工作人员只执行一个任务,因此每个工作人员只执行一次attach,而不是trials / 3 次。它还会导致更少但更大的套接字操作,这可以在大多数系统上更有效地执行,但在这种情况下,关键问题是attach

【讨论】:

  • 有 4 名工人,这需要 9.2 秒。当我做 chunks=1 花了 28.18
  • 我打算给维护者发电子邮件让他们知道,但这是革命分析,我不想被销售人员打中。
  • @DeanMacGregor 别担心:我已经联系过他们,特别是因为我发现了真正的潜在问题并相信我已经解决了它。我现在正在与 Revolution 合作,以便在 doSNOW 和 doParallel 的下一个版本中修复它。
猜你喜欢
  • 2018-10-08
  • 1970-01-01
  • 2021-06-10
  • 1970-01-01
  • 2017-09-04
  • 2021-09-16
  • 1970-01-01
  • 2015-08-31
  • 1970-01-01
相关资源
最近更新 更多