私はF#で計算集中的な仕事をしています。 .Net Task Parallel Libraryを使用するArray.Parallel.map
のような関数は、私のコードを指数関数的にスピードアップし、実際には最小限の努力をしています。F#PSeq.iterはすべてのコアを使用していないようです
しかし、メモリの問題から、私はシーケンス式の中で怠惰に評価できるようにコードの部分を作り直しています。それは評価する時間が来たときに私が使用:
// processor and memory intensive task, results are not stored
let calculations : seq<Calculation> = seq { ...yield one thing at a time... }
// extract results from calculations for summary data
PSeq.iter someFuncToExtractResults results
の代わりに:
私ははっきりと(ギアに私のコンピュータキック上のすべてのコアを見ることができますArray.Parallel機能のいずれかを使用して〜 100%CPU使用率)。ただし、余分なメモリが必要なため、プログラムは終了しませんでした。
私がプログラムを実行すると、PSeq.iterのバージョンでは、約8%のCPU使用率(および最小RAM使用率)しかありません。
So:PSeqのバージョンが非常に遅くなる理由はありますか?それは怠惰な評価のためですか?私は行方不明のいくつかの魔法は "並行する"ものですか?
おかげで、
その他のリソース、両方のソースコードの実装(彼らは.NETの異なるパラレルライブラリを使用するように見える):
https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/array.fs
https://github.com/fsharp/powerpack/blob/master/src/FSharp.PowerPack.Parallel.Seq/pseq.fs
EDIT:さらに追加コード例と詳細の詳細
コード:
配列
// processor and memory intensive task, results are not stored let calculations : seq<Calculation> = seq { for index in 0..data.length-1 do yield calculationFunc data.[index] } // extract results from calculations for summary data (different module) PSeq.iter someFuncToExtractResults results
アレイ
// processor and memory intensive task, storing these results is an unnecessary task let calculations : Calculation[] = Array.Parallel.map calculationFunc data // extract results from calculations for summary data (different module) Array.Parallel.map someFuncToExtractResults calculations
詳細:
- intermediatを記憶しますeアレイバージョンは10分以内に速く実行されますが、クラッシュする前に~70GBのRAMを使用します(64GB物理、残りのページング)
- seqバージョンは34分を要し、RAMの一部を使用します(約30GB)
- 私は計算している10億の値があります。したがって、10億倍(それぞれ64bits)= 7.4505806GBです。もっと複雑な形式のデータがあります。不要なコピーがいくつかありますので、現在の大量のRAM使用量を掃除しています。
- はいアーキテクチャーはあまり良くありません。プログラムの最適化やデータをより小さなチャンクにまとめようとする私の最初の部分は遅延評価です。
- 小さなデータセットでは、結果。
- @pad、私はあなたが提案したPSeqを試しました。計算[]を与えたときに正しく動作しているように見えましたが、RAMの問題が残っていました(最終的にはクラッシュしました)
- コードの要約部分と計算部分の両方がCPU集中です私はちょうどあなたの更新された情報に基づいて、一度
レイジー評価は並列実行ではうまくいきません。公正であるには、同じ 'Calculation [] 'を' PSeq.iter'と 'Array.Parallel.map'に渡します。 'Calculation'と' someFuncToExtractResults'の詳細がなくてもその理由を伝えることは不可能です。 – pad
提案してくれてありがとうございました。私はこれを試しましたが、PSeqはレイジーシーケンスで配列を与えられたときにうまく動作します...しかし、RAMの問題は解決しません。 –