clojure - Clojure 中 pmap 的更好替代方案,用于在大数据上并行化适度廉价的函数?

标签 clojure parallel-processing

使用 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

就我而言,映射函数并不昂贵,但序列很大(数百万条记录)。我认为创建和取消引用许多 future 的成本是并行增益在开销中损失的地方。

我对 pmap 的理解正确吗?

在 clojure 中是否有比 pmap 更好的模式来实现这种低成本但大量重复的处理?我正在考虑以某种方式对数据序列进行分块,然后在更大的 block 上运行线程。 这是一种合理的方法吗?哪些 Clojure 习惯用法可行?

最佳答案

这个问题:how-to-efficiently-apply-a-medium-weight-function-in-parallel也在非常相似的环境中解决了这个问题。

当前最好的答案是使用分区将其分成 block 。然后将映射函数 pmap 到每个 block 上。然后重新组合结果。映射缩减风格。

关于clojure - Clojure 中 pmap 的更好替代方案,用于在大数据上并行化适度廉价的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2103599/

相关文章:

javascript - 需要相当于 three.js javascript 'loadTexture' 语句的 clojurescript

hadoop - 可以使用 Map Reduce 和 Hadoop 并行处理批处理作业吗?

c++ - 在 OpenMP 循环中调用 QApplication::processEvents()?

java - 在 Java 中并行化阻塞调用

algorithm - 在 Clojure 中实现 Minimax 算法 - 具有多个递归调用的条件函数

xml - 无法在 Clojure 中使用命名空间 clojure.data.zip.xml

clojure - 应用 map 组合 - 没有按我的预期工作

haskell - 在 Clojure 中,有没有类似 Haskell 的 on 的功能?

multithreading - 将递归分成更细的递归粒度

python - 为什么h5py数据集并行分配没有输出?