一起使用多个线程用于单个进程

时间:2018-05-24 06:14:30

标签: java multithreading optimization cpu-usage

我有一个我作为基准测试编写的因子程序,用一个线程计算100万的阶乘需要3分钟。我很好奇是否有可能为同一算法分配多个线程,而不是同时运行,但总体上提高了处理速度并减少了运行算法所需的时间。我认为这是可能的,因为超级计算机有很多线程,通常是平均CPU频率。

2 个答案:

答案 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