2

我正在尝试使用foreach来进行并行计算。如果有少量的值需要迭代,它工作得很好,但在某些时候它会变得非常慢。这是一个简单的例子:

library(foreach)
library(doParallel)

registerDoParallel(8)

out1 <- foreach(idx=1:1e6) %do%
    {
        1+1
    }

out2 <- foreach(idx=1:1e6) %dopar%
    {
        1+1
    }

out3 <- mclapply(1:1e6,
                 function(x) 1+1,
                 mc.cores=20)

out1并且out2需要很长时间才能运行。只要我让它们运行,它们甚至都不会产生多个线程。out3几乎立即产生线程并且运行得非常快。是否foreach在进行某种无法很好扩展的初始处理?如果是这样,是否有一个简单的解决方法?我真的更喜欢foreach.

我还应该注意,我尝试并行化的实际代码比 1+1 复杂得多。我仅将其作为示例显示,因为即使使用这个简单的代码 foreach 似乎也在做一些非常慢的预处理。

4

1 回答 1

2

forach/doParallel 小插图说(比你的代码小得多):

请注意,这不是 doParallel 的实际用途。这是我们用于并行计算的“Hello, world”程序。它会测试一切是否已正确安装和设置,但不要期望它比顺序 for 循环运行得更快,因为它不会!sqrt 执行速度太快,不值得并行执行,即使有大量迭代也是如此。对于小任务,调度任务和返回结果的开销可能大于任务本身执行的时间,导致性能不佳。此外,这个例子没有使用 sqrt 的向量功能,它必须获得良好的性能。这只是一个测试和教学示例,而不是基准。

因此,它可能不是更快的设置的性质。

而是尝试不使用并行化但使用矢量化:

q <- sapply(1:1e6, function(x) 1 + 1 )

它与您的示例循环完全相同,并且在一秒钟内完成。现在试试这个(它在同一时间仍然完全相同:

x <- rep(1, n=1e6)
r <- x + 1

它立即增加 1e6 1sa 1。(矢量化的力量……)

根据我的个人经验,与使用存储库 Bioconda 中的生物信息学软件包相比,foreach与 with的组合要慢得多。(我是一名生物信息学家,在生物信息学领域,我们经常有大量计算量大的东西,因为我们有几个千兆字节的单个数据文件要处理——而且其中有很多)。我尝试使用您的功能,它使用所有分配的 CPU 100%(通过在作业执行期间运行进行测试)整个过程耗时 17 秒。doParallelBiocParallelBiocParallelhtop

当然 - 对于您的轻量级示例,这适用:

调度任务和返回结果的开销可能大于执行任务本身的时间

无论如何,它似乎比doParallel. 因此,如果您要完成计算量大的任务,请使用它。这是我如何做到的代码:

# For bioconductor packages, the best is to install this:
install.packages("BiocManager")

# Then activate the installer
require(BiocManager)

# Now, with the `install()` function in this package, you can install
# conveniently Bioconductor packages like `BiocParallel`
install("BiocParallel")

# then, activate it
require(BiocParallel)

# initiate cores:
bpparam <- bpparam <- SnowParam(workers=4, type="SOCK") # 4 or take more CPUs

# prepare the function you want to parallelize
FUN <- function(x) { 1 + 1 }

# and now you can call the function using `bplapply()`
# the loop parallelizing function in BiocParallel.
s <- bplapply(1:1e6, FUN, BPPARAM=bpparam) # each value of 1:1e6 is given to 
# FUN, note you have to pass the SOCK cluster (bpparam) for the 
# parallelization

有关更多信息,请转到BiocParallel 包的小插图。看看 bioconductor 它提供了多少包,并且都有据可查。我希望这对您未来的并行计算有所帮助。

于 2018-10-11T20:55:57.230 回答