clojureを使用して簡単な操作を効率的に大規模なシーケンスに並列で適用する方法を理解しようとしています。並列ソリューションを使用して、マシン上の複数のコアを利用してスピードアップを実現したいと考えています。Clojureを使用して多数の数値の合計を計算するには
私は、入力seqのすべてのアイテムの未来を作成するオーバーヘッドを減らすために、partition-allと組み合わせてpmapを使用しようとしています。残念ながら、partition-allは各パーティションseqの完全な評価を強制します。これは私のマシン上でOutOfMemoryErrorを引き起こします。
(defn sum [vs]
(reduce + vs))
(def workers
(+ 2 (.. Runtime getRuntime availableProcessors)))
(let
[n 80000000
vs (range n)]
(time (sum vs))
(time (sum (pmap sum (partition-all (long (/ n workers)) vs)))))
大きな入力セットに合計を適用してシリアル実装のパフォーマンスを上げるにはどうすればよいですか?レデューサーライブラリを指摘して@Arthur Ulfeldtへ
ソリューション
感謝。ここに、減速器を使用したソリューションがあります。このコードは、マルチコアマシンで実行した場合の予想されるパフォーマンスの向上を示しています。チャンクを試してみてください、私はかなり大きな塊がスイッチングを克服するために必要であることを見出したのpmapおよび将来のオーバーヘッドを使用する場合
(require '[clojure.core.reducers :as r])
(let
[n 80000000
vs #(range n)]
(time (reduce + (vs)))
(time (r/fold + (vs)))
は間違った方法塊です周り? '(partition-all workers vs)'は長さ 'workers 'の'(/ n workers) 'シーケンスを作成します。あなたは '(パーティション全部(長い(/ n人)対)vs)'をしたくないですか? –
@A.Webb、訂正していただきありがとうございます。私はその問題を修正するつもりです。この修正により、並列バージョンは少し速くなりますが、それでもシリアル実装を破ることはできず、非常に大きな入力ではメモリ不足になります。 –