我有一个我作为基准测试编写的因子程序,用一个线程计算100万的阶乘需要3分钟。我很好奇是否有可能为同一算法分配多个线程,而不是同时运行,但总体上提高了处理速度并减少了运行算法所需的时间。我认为这是可能的,因为超级计算机有很多线程,通常是平均CPU频率。
答案 0 :(得分:2)
正如Alex所说,这个问题很容易在多个线程中传播。
让我们看看使用Java8流的单线程实现:
Stream<BigInteger> numbers = LongStream.rangeClosed(1, 1_000_000).mapToObj(BigInteger::valueOf);
BigInteger reduced = numbers.reduce(BigInteger.ONE, BigInteger::multiply);
现在让我们看看它的多线程版本:
Stream<BigInteger> numbers = LongStream.rangeClosed(1, 1_000_000).mapToObj(BigInteger::valueOf);
numbers = numbers.parallel();
BigInteger reduced = numbers.reduce(BigInteger.ONE, BigInteger::multiply);
(是的,唯一的区别是numbers = numbers.parallel();
- 溪流之美)
第二个多比第一个快(取决于您拥有的真实和超线程CPU的数量),但得到相同的结果。
由于某种原因我还无法完全解释,并行版本比非并行版本更多更快。它可能与内存使用有关。在我的4核2.5Ghz i7 MacBook Pro上,使用并行版本计算需要5.8秒,但非并行版本即使在10分钟(100万)内也无法完成。
对于100,000,并行版本要快得多:并行版本为90毫秒,非并行版本为2500毫秒(在9次预热迭代后测量第10次迭代)。
答案 1 :(得分:1)
显然,如果您拥有k
个处理器,则可以将n
factorial的工作拆分为并行查找[2, n * (1/k)], ... [n * ((k-1)/k) + 1, n]
的产品以获取数字P_1, ..., P_k
,然后整体factorial是n! = P_1 * ... * P_k
。