【问题标题】:Parallel Sieve of Eratosthenes using Clojure Reducers使用 Clojure Reducers 的 Eratosthenes 平行筛
【发布时间】:2016-03-06 05:57:52
【问题描述】:

我已经使用 Clojure 的标准库实现了埃拉托色尼筛。

(defn primes [below]
  (remove (set (mapcat #(range (* % %) below %)
                       (range 3 (Math/sqrt below) 2)))
          (cons 2 (range 3 below 2))))

我认为这应该符合并行性,因为没有递归,并且可以删除 remove 和 mapcat 的 reducer 版本。这是我想出的:

(defn pprimes [below]
  (r/foldcat
   (r/remove
    (into #{} (r/mapcat #(range (* % %) below %)
                        (into [] (range 3 (Math/sqrt below) 2))))
    (into [] (cons 2 (range 3 below 2))))))

我已经将初始集合和生成的倍数倒入向量中,因为我知道 LazySeq 不能折叠。还有,最终实现集合使用r/foldcat。

我的问题是这比第一个版本慢了一点。

(time (first (primes  1000000))) ;=> approx 26000 seconds
(time (first (pprimes 1000000))) ;=> approx 28500 seconds

协调进程的开销是否过多,还是我使用减速器有误?

【问题讨论】:

    标签: clojure parallel-processing primes sieve-of-eratosthenes reducers


    【解决方案1】:

    感谢 leetwinski,这似乎可行:

    (defn pprimes2 [below]
      (r/foldcat
       (r/remove
        (into #{} (r/foldcat (r/map #(range (* % %) below %)
                                    (into [] (range 3 (Math/sqrt below) 2)))))
        (into [] (cons 2 (range 3 below 2))))))
    

    显然我需要添加另一个折叠操作才能并行映射#(range (* % %) below %)

    (time (first (pprimes   1000000))) ;=> approx 28500 seconds
    (time (first (pprimes2  1000000))) ;=> approx  7500 seconds
    

    编辑:上面的代码不起作用。 r/foldcat 没有连接复合数,它只是返回每个素数的倍数向量。最终结果是一个 2 和所有奇数的向量。将r/map 替换为r/mapcat 会给出正确答案,但它再次比原来的primes 慢。

    【讨论】:

      【解决方案2】:

      请记住,r/mapcatr/remove 本身并不平行,您只是在生产可折叠的集合,而这些集合又可以通过 r/fold 进行并行化。在您的情况下,唯一的并行操作是r/foldcat,这是根据文档“等效于(fold cat append! coll)”,这意味着您可能会并行执行append!,这根本不是您想要的。

      为了使其并行,您可能应该使用 r/foldremove 作为 reduce 函数和 concat 作为组合函数,但我猜它不会真正让您的代码更快,因为您的性质算法(我的意思是你会尝试从集合的每个块中删除一大组项目)

      【讨论】:

      • 感谢您的回复!我知道 r/mapcat、r/remove 等只是将来要执行的配方,但我的印象是最后的 r/foldcat 将并行运行每个操作。你让我想到可能需要再折叠一次。毕竟#(range (* % %) below %) 的所有映射跨越 2
      猜你喜欢
      • 2011-02-28
      • 1970-01-01
      • 1970-01-01
      • 2014-01-07
      • 1970-01-01
      • 2013-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多