代码之家  ›  专栏  ›  技术社区  ›  Alex Stoddard

在Clojure中更好地替代PMAP来并行处理大数据上中等成本的函数?

  •  29
  • Alex Stoddard  · 技术社区  · 15 年前

    使用clojure,我有一个序列中非常大量的数据,我想用相对较少的核心(4到8)并行处理它。

    最简单的方法是使用 pmap 而不是 map ,在数据序列上映射我的处理函数。 但在我的情况下,协调开销会导致净损失 .

    我想原因是 PMAP 假设跨数据映射的函数非常昂贵 . 查看pmap的源代码,它似乎构造了一个 future 对于序列的每个元素,这样函数的每次调用都发生在一个单独的线程上(在可用核心的数量上循环)。

    以下是PMAP来源的相关部分:

    (defn pmap
      "Like map, except f is applied in parallel. Semi-lazy in that the
      parallel computation stays ahead of the consumption, but doesn't
      realize the entire result unless required. Only useful for
      computationally intensive functions where the time of f dominates
      the coordination overhead."
      ([f coll]
       (let [n (+ 2 (.. Runtime getRuntime availableProcessors))
             rets (map #(future (f %)) coll)
             step (fn step [[x & xs :as vs] fs]
                    (lazy-seq
                     (if-let [s (seq fs)]
                       (cons (deref x) (step xs (rest s)))
                       (map deref vs))))]
         (step rets (drop n rets))))
      ;; multi-collection form of pmap elided
    
    

    在我的例子中,映射函数没有那么昂贵,但是序列是巨大的(数以百万计的记录)。我认为,创造和取消参考许多期货的成本是平行收益在管理费用中损失的地方。

    我是否理解 PMAP 对的?

    在Clojure中,有没有一种更好的模式可以比 PMAP ?我正在考虑以某种方式对数据序列进行分块,然后在更大的块上运行线程。 这是一个合理的方法吗?Clojure的成语是什么?

    4 回复  |  直到 15 年前
        1
  •  20
  •   Community Daniel Roseman    7 年前

    这个问题: how-to-efficiently-apply-a-medium-weight-function-in-parallel 在非常相似的背景下解决这个问题。

    目前最好的答案是使用 partition 把它分成块。然后将映射函数映射到每个块上。然后重新组合结果。地图缩小样式。

        2
  •  5
  •   Runevault    15 年前

    遗憾的是,这还不是一个有效的答案,但未来要注意的是Rich在Java 7中使用的叉/连接库的工作。如果你看看他在Github的par分支,他已经做了一些工作,最后我看到早期的回报是惊人的。

    富人尝试的例子。

    http://paste.lisp.org/display/84027

        3
  •  2
  •   Joffer    11 年前

    在前面的答案中提到的这个和类似的线程的分叉/连接工作最终会像 reducers 图书馆,可能值得一看。

        4
  •  0
  •   edbond    15 年前

    您可以使用手工实现的某种映射/减少。也可以看看 swarmiji 框架。

    “一个分布式计算系统,帮助在核心和处理器之间并行编写和运行Clojure代码。”