Scala自己并行做什么吗?

时间:2011-06-07 19:26:14

标签: scala collections parallel-processing

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

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

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

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

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

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

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

  4. 我现在有两个问题:

    • 为什么我的所有4个核心都在旋转,尽管没有任何并行运行。

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

    有关于此的任何想法吗?

1 个答案:

答案 0 :(得分:9)

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

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

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