将多个线程共同用于单个进程



我有一个阶乘程序作为基准测试,用单个线程计算 100 万的阶乘需要 3 分钟。我很好奇是否可以将多个线程分配给同一算法,而不是同时运行,而是共同提高处理速度并减少运行算法所需的时间。我假设这是可能的,因为超级计算机有许多线程,并且通常平均CPU频率。

正如 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 次迭代(。

显然,如果你有k处理器,你可以将n阶乘的工作拆分为并行查找[2, n * (1/k)], ... [n * ((k-1)/k) + 1, n]的乘积以获得数字P_1, ..., P_k,那么整体阶乘是n! = P_1 * ... * P_k

最新更新