scala - Scala 是否可以自己并行执行任何操作?

标签 scala collections parallel-processing

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

该程序计算 30 个尺寸增加的迷宫。使用 a for comprehension over (1 to 30)

由于最新版本的并行集合框架可用,我想试一试,希望能获得一些性能提升。

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

  • 当在没有任何远程并行调用的情况下运行时,它仍然显示我机器的 4 个内核中的每个内核的处理器负载约为 30%。
  • 当我用 (1 to 30).par 替换 Range 1 to 30 时,所有内核上的 CPU 负载上升到大约 80%(这是我预期的)。迷宫完成的顺序或多或少是随机的(这是我预期的)。所有迷宫的总时间保持不变。
  • 用它们的并行计数器部件替换一些内部使用的集合似乎确实有效果。

  • 我现在有两个问题:
  • 为什么我让所有 4 个内核都在旋转,尽管没有任何并行运行的内核。
  • 无论是否并行运行,程序仍然需要相同时间的可能原因是什么。除了 CPU 周期(没有 IO,没有网络,通过 -Xmx 设置获得大量内存)之外,没有其他明显的瓶颈

  • 对此有何想法?

    最佳答案

    每个核心版本 30% 只是一个糟糕的调度程序(听起来像 Windows 7),它非常频繁地将进程从一个核心迁移到另一个核心。对于您的进程,每个内核 (1/4) 可能更接近 25%,再加上其他负载占 30%。如果您在 Linux 下运行相同的示例,您可能会看到一个核心。

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

    编辑:如果 1..30 中的每一个都代表一些更大的工作量(比如解决迷宫),那么如果每个工作单元大致相同,那么自动并行化将工作得更好。想象一下,你有 29 个简单的迷宫和一个非常难的迷宫。第 30 个迷宫仍将与其他所有内容连续(或非常接近)运行)。如果您的迷宫的复杂性随着数量的增加而增加,请尝试按顺序生成它们 30 to 1 by -1以便最重要的任务先进行。将其视为背包问题的脑残解决方案。

    关于scala - Scala 是否可以自己并行执行任何操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6270522/

    相关文章:

    scala - 如何在 Scala 测试中将模拟调用与通配符匹配?

    scala - 动态构建 Spark SQL 查询

    java - 如何根据自定义顺序对 java 列表进行排序

    r - 带有 doSMP 和 foreach 的并行随机森林大大增加了内存使用量(在 Windows 上)

    c++ - Qimage setPixel with openmp parallel for 不起作用

    scala - .parallelize(...) 是 Apache Spark 中的惰性操作吗?

    java - 从具有附加元素的给定列表派生列表

    java - 如何对对象类型列表进行排序

    c++ - 能否使用 OpenMP 并行化以下 C++ 代码以获得更好的性能?

    scala - 使用MacPorts安装Scala后,找不到scala命令