【发布时间】:2015-02-13 09:23:23
【问题描述】:
如何有效地并行计算 pi(仅作为示例)?
这可行(在我的机器上大约需要 15 秒):
Stream.iterate(1d, d->-(d+2*(Math.abs(d)/d))).limit(999999999L).mapToDouble(d->4.0d/d).sum()
但以下所有并行变体都会遇到 OutOfMemoryError
DoubleStream.iterate(1d, d->-(d+2*(Math.abs(d)/d))).parallel().limit(999999999L).map(d->4.0d/d).sum();
DoubleStream.iterate(1d, d->-(d+2*(Math.abs(d)/d))).limit(999999999L).parallel().map(d->4.0d/d).sum();
DoubleStream.iterate(1d, d->-(d+2*(Math.abs(d)/d))).limit(999999999L).map(d->4.0d/d).parallel().sum();
那么,我需要做什么才能并行处理这个(大)流? 我已经检查过自动装箱是否导致内存消耗,但事实并非如此。这也有效:
DoubleStream.iterate(1, d->-(d+Math.abs(2*d)/d)).boxed().limit(999999999L).mapToDouble(d->4/d).sum()
【问题讨论】:
-
刚刚从@Brian-Goetz 找到一个引用:“现在的简单规则是:最后一次调用获胜,并控制整个管道的执行模式。”所以我在哪里添加
.parallel()call 并不重要。但仍然:如何在执行过程中不遇到 OutOfMemeoryError? -
也许给它更多的内存只是在火上浇油:),你是否给你的 JVM 提供了最大内存大小的任何参数?请参阅此 SO 帖子:stackoverflow.com/questions/14763079/…
-
增加限制不是真正的解决方案,因为会有另一个大小的流来破坏它。我想知道内存是用来做什么的以及如何规避它。
-
出于好奇:考虑到元素的迭代定义,您认为并行执行可以获得什么?
-
这是一个奇怪的期望。您的 source 不能并行处理,因为每个值都依赖于前一个值。相比之下,最终的
sum操作是完全可并行的。
标签: java parallel-processing java-8 java-stream