純粋な計算に接続されたHaskellの並列ストラテジーの使用法と説明がよく見られます(たとえば、fib
)。しかし、私はモナド構造で使用されることはよくありません:ST s
またはIO
に適用した場合、par
の効果と関連する関数の合理的な解釈がありますか?そのような使用からスピードアップが得られるでしょうか?モナドでの並列ストラテジーの使用
答えて
IOモナドの並列性は、より正確には「並行性」と呼ばれ、モジュールのforkIO
とフレンドによってサポートされています。
STモナドを並列化することの難しさは、STが必然的にシングルスレッドであることです。これがその目的です。原則として並列評価をサポートすることができるSTモナドControl.Monad.ST.Lazy
の怠惰な変形がありますが、私はこれをやろうとしている人は知らないのです。
Evalと呼ばれる並列評価用の新しいモナドがあります。このモナドはparallel packageの最新バージョンにあります。最近はpar
とpseq
の代わりにEval
のモナドをrpar
とrseq
で使用することをお勧めします。なぜなら、より堅牢で読みやすいコードにつながるからです。例えば、通常のfib
例は
fib n = if n < 2 then 1 else
runEval $ do
x <- rpar (fib (n-1))
y <- rseq (fib (n-2))
return (x+y)
を書き込むことができ、これは理にかなっているが、一般的に、あなたがそれを行うべきではない、いくつかの状況があります。以下の調べ:
doPar
で
doPar =
let a = unsafePerformIO $ someIOCalc 1
b = unsafePerformIO $ someIOCalc 2
in a `par` b `pseq` a+b
、a
ための計算を巻き起こしている、メインスレッドはb
を評価します。しかし、メインスレッドがb
の計算を終了した後、a
も評価される可能性があります。今度は、a
を評価する2つのスレッドがあります。つまり、IOアクションの一部が2回(またはそれ以上)実行されることを意味します。しかし、一方のスレッドがa
の評価を終了すると、もう一方のスレッドはこれまでの処理を破棄します。これを安全にするには、実際にはいくつかのことが必要です。
- IOアクションを複数回実行することは安全です。
- IOアクションの一部のみを実行することは安全です(クリーンアップがないなど)
- IOアクションには競合条件がありません。あるスレッドが
a
を評価する際に何らかのデータを変更すると、他のスレッドもa
で動作しますか?おそらくそうではありません。 - どれ外国呼び出しがされている再入あなた
someIOCalc
このsomeIOCalc n = do prelaunchMissiles threadDelay n launchMissiles
のように見える場合、それは
par
とでこれを使用するために絶対に安全ではありません
(あなたはもちろん、一般的に同時実行のためにこれを必要とします) unsafePerformIO
。
今、それはこれまでに価値がありますか?多分。スパークは安く、スレッドよりも安いので、理論的にはパフォーマンスが向上するはずです。実際には、それほど多くはないでしょう。ローマLeschinskyは素敵なblog post about thisを持っています。
私は個人的には、約forkIO
の理由を考えるのがずっと簡単です。
- 1. Haskellで並列ストラテジーを使用した場合のスローダウン
- 2. IOモナド内のモナドを使用する
- 3. 他のモナドの関数であるIOモナドでの使用
- 4. システムテスト用の実用的なモナドDSL:並行性とエラー処理
- 5. 接続文字列RsaProtectedConfigurationProviderストラテジー
- 6. Pythonの値の欠如ストラテジー
- 7. プロジェクトベースのマトリックス認証ストラテジーで列を追加する方法
- 8. Passportストラテジー内のAsync/Await Request
- 9. カスタムの多分モナド実装でのLINQクエリ構文の使用
- 10. データフローの使用例 - 並列ファイル処理
- 11. デザインパターン - ストラテジーとブリッジ(オーバーラップデザイン)
- 12. ストラテジーまたはアダプターパターン?
- 13. StateTモナドを使用したループ
- 14. モナドを使用したデータ構造
- 15. GNU並列を使用してループのためのbashを並列化する
- 16. .net環境でモナドの使用法はありますか?
- 17. java用のGoogleアプリケーションエンジンで並列処理を使用する
- 18. モナド内部モナド変換器の結果
- 19. モナド変圧器モナドの複製
- 20. イベントベースの非同期パターンでのタスク並列ライブラリの使用
- 21. r(Windows 7の場合)でのwordnetの並列使用
- 22. GNU並列を使用してシェルのforループを並列化する方法
- 23. なぜモナドでモナドが必要なのでしょうか
- 24. RubyでTSortを使用して配列の並べ替えと並べ替え
- 25. OpenMPを使用したC++でのループの並列化
- 26. モナド対モナド変圧器
- 27. 並列libstdC++モードでイテレータ用の並列for_eachアルゴリズムを使用していません
- 28. QT座標変換ストラテジー
- 29. JavaScript用の並列HTTPリクエストライブラリ
- 30. ストラテジーなどを電子メールの送信に使用する方法
IO操作を特定の順序で実行する(たとえば、ファイルを開くよりも、ファイルを開くことよりも閉じるなど)。そこでは何を並列化したいですか? – helium
@helium:これは主に、可変データまたはFFIを使用していると思われます。 –
私はこれを疑問に思っています。私はしばしばいくつかの大きなファイル(100メガ)を開いて、それらを並列スレッドで解凍し、開いた後にそれらを使って作業します。彼らは素晴らしいパフォーマンスの向上を見るのに十分な大きさですが、私はそれらをメモリに保持するのに十分なほど小さいです。私はハスケルでこれをどうやってするのか疑問に思っています。 –