Boost.Asioを使って、スレッドプールを利用した簡単な並列アルゴリズムを実装してみた。名前は適当にTiny Parallel Library(むしろ"Toy"の方が似合う気がする)。
概要
実装した並列アルゴリズムは下記3つのみで、インタフェースはIntel TBBおよびMicrosoft PPL互換としている。
- parallel_for_each
- parallel_for
- parallel_invoke
既定動作では 論理プロセッサ数-1 のワーカスレッドプールを生成し、ワーカスレッド数=論理プロセッサ数として並列アルゴリズムを実行する*1。並列ループparalle_for_each, parallel_forは、入力範囲を論理プロセッサ数で単純にブロックへ分割して並行処理を行う。なお、並列アルゴリズムは入れ子構造としても正常に動作する*2。(例:parallel_invokeで呼び出した関数内でparallel_forを行うなど。)
注意:ライブラリ実装では例外について考慮していない!!(ToDo:Boost.Asioの例外処理について調べる)
ライブラリコード
メモ
- Boost.Atomicが欲しかった。Boost.Interprocess内部実装にatomic整数があったためこちらで代用。
- impl::waiter::~waiter()で「自スレッドで処理可能なタスクが存在しない」かつ「他スレッドでのタスク完了を待機中」の場合、waiter::counter_変数への激しいポーリング処理が発生する。この状況が生じるのは「並列アルゴリズムを組み合わせた」または「並列化したタスクの処理時間が不均一」のとき。
- 単純な利用ケースに限ればIntel TBBに近い性能がでるが、並列アルゴリズムを組み合わせるような複雑なケースでは明らかに劣る。
- 並列アルゴリズムを入れ子にする(parallel_invokeを用いる関数の再帰呼び出しなど)とコールスタック消費が激しい。この観点ではIntel TBBが明らかに優れていた。