r - foreach 非常慢,有大量值
问题描述
我正在尝试使用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 似乎也在做一些非常慢的预处理。
解决方案
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 1
sa 1
。(矢量化的力量……)
根据我的个人经验,与使用存储库 Bioconda 中的生物信息学软件包相比,foreach
与 with的组合要慢得多。(我是一名生物信息学家,在生物信息学领域,我们经常有大量计算量大的东西,因为我们有几个千兆字节的单个数据文件要处理——而且其中有很多)。我尝试使用您的功能,它使用所有分配的 CPU 100%(通过在作业执行期间运行进行测试)整个过程耗时 17 秒。doParallel
BiocParallel
BiocParallel
htop
当然 - 对于您的轻量级示例,这适用:
调度任务和返回结果的开销可能大于执行任务本身的时间
无论如何,它似乎比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 它提供了多少包,并且都有据可查。我希望这对您未来的并行计算有所帮助。
推荐阅读
- django - Django + Heroku + GoDaddy = SSL_ERROR_INTERNAL_ERROR_ALERT
- nlp - Pytorch:如何实现嵌套转换器:单词的字符级转换器和句子的单词级转换器?
- node.js - Async-Await 仍在异步运行
- java - 为什么我不断收到“不是 JSON 数组”?
- react-native - 如何有条件地为 web 导入 react-native-vector-icons dist
- c# - 压缩 pdf 文档时压缩存档无效
- python - 如何将颜色图作为散点图的迭代器包含在内
- python-3.x - 创建一个已知长度的重复二进制模式
- c# - 制作弹性物体 Unity3D
- javascript - 可以从页面访问原始 Javascript 源吗?