Scala自己并行做什么吗?

Jen*_*der 7 collections parallel-processing scala

我有一个小程序创建一个迷宫.它使用了大量的集合(默认变体,它是不可变的,或者至少用作不可变的).

该程序计算30个增加尺寸的迷宫.用于理解(1到30)

由于最新版本的并行集合框架可用,我认为可以给它一个旋转,希望获得一些性能提升.

这失败了,当我调查一下时,我发现了以下内容:

  1. 在没有任何远程并行任何调用的情况下运行时,它仍然在我的机器的4个核心中的每个核心上显示大约30%的处理器负载.

  2. 当我用(1到30)替换范围1到30时.所有内核(我预期的)CPU负载上升到大约80%.迷宫完成的顺序或多或少随机(我预期).所有迷宫的总时间保持不变.

  3. 用它们的并行计数器部件替换一些内部使用的集合似乎确实有效.

我现在有两个问题:

  • 为什么我要将所有4个核心旋转,尽管没有任何并行运行的核心.

  • 无论是否并行运行,程序仍然需要同时执行的原因可能是什么原因.除了CPU周期(没有IO,没有网络,大量内存通过-Xmx设置)没有明显的其他瓶颈

有什么想法吗?

Ben*_*son 9

每个核心版本的30%只是一个糟糕的调度程序(听起来像Windows 7)非常频繁地将进程从核心迁移到核心.对于您的工艺来说,每核心(1/4)可能接近25%,而其他负载则为30%.如果你在Linux下运行相同的例子,你可能会看到一个核心挂钩.

当你转换为(1 to 30).par,你开始真正使用所有核心的线程,但分配这么少的工作,然后收集结果的同步开销抵消了并行性的收益.你需要将你的工作分解成更大的独立块.

编辑:如果1..30中的每一个代表一些更大量的工作(比如解决迷宫),那么如果每个工作单元大致相同,则自动并行化将更好地工作.想象一下,你有29个简单的迷宫和一个非常非常坚硬的迷宫.第30个迷宫仍将连续(或非常接近)与其他所有东西一起运行.如果您的迷宫按数量增加复杂性,请尝试按顺序生成它们,以便30 to 1 by -1最大的任务先行.可以把它想象成背包问题的脑死亡解决方案.