スレッドを用いた並列プログラミング
本書の前半は「並列」を、後半は「並行」を扱ってきました。13章では、並行プログラミングの技術(つまりスレッド)を使って並列プログラミングをする話です。
純粋な並列プログラミングが使えない問題は、「I/O をしなければならない問題」「内部的な非決定性に依存するアルゴリズム」があるとのこと。
まあ、スレッドによる並行処理を複数の CPU コアで動かすというだけの話かなと思います。ただ、スレッドをむやみにたくさん作ってもオーバーヘッドが大きくなって性能向上にならないので、そこを解決する必要があります。
例題:ファイル探索
ファイルシステムを検索して特定の名前のファイルを見つける find プログラムが題材です。
最初に「直列版」の findseq.hs が出てきます。これが基本形で、これをどう並列にするか。
findpar.hs : Async を使って素朴に並列化したもの。サブディレクトリごとに Async を生成するのでパフォーマンスが悪い。
findpar2.hs / findpar3.hs : スレッド数を制限したもの。制限をかけるためにセマフォを利用している。findpar2 は MVar でセマフォを実装していてあまり効率が良くない。findpar3 は IORef でセマフォを実装していて効率が良くなっている。
findpar4.hs : Async バージョン(findpar.hs)で、Async の代わりに ParIO モナドを活用したもの。パフォーマンスが良い。
後の方で「実はこんな簡単で便利なものがあるんだよ〜」と出してくるのは、この本の定番パターンですね。
ただ、ParIO はエラー処理がないという問題があり、エラー処理をどうするかは読者への課題となっています。とは言っても、それに対応したサンプルコード findpar5.hs は用意されていますが。
今後
並列並行本も、あとは 14 章と 15 章だけになりました。最後まで読み終えたら、Umekita.hs として次に何をやるかは未定です。もう少し参加者が増えてほしい・・・。
つらつらと案を考えてみる。
- 読書会 : すごいHaskellたのしく学ぼう! (前にも読んだけどもう一度読んでみる)
- 読書会 : 関数プログラミング実践入門 ──簡潔で、正しいコードを書くために (WEB+DB PRESS plus)
- 読書会 : Real World Haskell―実戦で学ぶ関数型言語プログラミング
- Haskell もくもく会をする
- Google Code Jam などの競技プログラミングの課題を Haskell で解いてみる会をする
興味ある方はご意見ください。