【问题标题】:how to efficiently apply a medium-weight function in parallel如何有效地并行应用中等权重函数
【发布时间】:2016-01-20 09:59:30
【问题描述】:

我希望将一个成本适中的函数并行映射到一个大型惰性序列上。 pmap 很棒,但我对上下文切换失去了很多。我认为我需要增加传递给每个线程的工作块的大小。

我写了一个函数来将 seq 分成块并将函数 pmap 到每个块上并重新组合它们。这“有效”,但结果并不引人注目。原始代码基本上是这样的:

(pmap eval-polynomial (range x) coificients)

我怎样才能在保持懒惰的同时真正挤压它?

【问题讨论】:

    标签: clojure parallel-processing


    【解决方案1】:

    使用partition 函数来分解你的range 序列怎么样? http://www.fatvat.co.uk/2009/05/jvisualvm-and-clojure.html

    上有一篇关于类似问题的有趣帖子

    【讨论】:

      【解决方案2】:

      我会从以下位置查看 ppmap 函数:http://www.braveclojure.com/zombie-metaphysics/。它允许您在指定块大小的同时进行 pmap。

      解决这个问题的方法是增加粒度,或者 每个并行任务完成的工作量。在这种情况下,任务 是将映射函数应用于集合的一个元素。 粒度不是以任何标准单位衡量的,但你会说 pmap 的粒度默认为 1。将粒度增加到两个 意味着您将映射函数应用于两个元素 而不是一个,所以任务所在的线程正在做更多的工作。 [...] 只是为了好玩,我们可以将这种技术推广到一个函数中 称为 pmap,用于分区 pmap。它可以接收多个 收藏,就像地图一样:

      (defn ppmap
        "Partitioned pmap, for grouping map ops together to make parallel
        overhead worthwhile"
        [grain-size f & colls]
        (apply concat
         (apply pmap
                (fn [& pgroups] (doall (apply map f pgroups)))
                (map (partial partition-all grain-size) colls))))
      (time (dorun (ppmap 1000 clojure.string/lower-case orc-name-abbrevs)))
      ; => "Elapsed time: 44.902 msecs"
      

      【讨论】:

      • 链接来来去去,stackoverflow 是永远的......你能否包括来自 braveclojure 的相关引用,以确保这个答案在长期内保持在上下文中。 (这个问题也差不多7岁了)
      【解决方案3】:

      如果您不介意一些有点异国情调的东西(以换取一些非常明显的加速),您可能还想查看 Penumbra-library 的作者所做的工作,它提供了easy access to the GPU

      【讨论】:

        【解决方案4】:

        我会看看 Fork/Join 库,它设置为集成到 JDK 7 中。它是一个轻量级线程模型,针对数据集上的非阻塞、分而治之的计算进行了优化,使用线程池、工作窃取调度程序和绿线。

        Some work 已将 Fork/Join API 包装到 par 分支中,但尚未合并到 main (yet) 中。

        【讨论】:

        • 是的,如果你能等到我愿意的 par 分支,我所看到的那一点点令人兴奋。
        • @Runevault 令人兴奋。似乎是 fork join 的包装器
        猜你喜欢
        • 2012-07-28
        • 2012-08-26
        • 2015-11-17
        • 1970-01-01
        • 2020-12-17
        • 2017-07-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多