プロファイリング情報について気になることがありました。
区間を区切って評価した時にキューの登録・取り出しを行う関数(en_que・de_que)の呼び出し回数が計算値と合いませんでした。しかも、測定する度に異なる数値になりました。
調べてみたところ、どうやら使用したプロファイラ( gprof )はマルチスレッドプログラムを正確に測定することはできないようでした。代わりに、Oprofileやperfというプロファイラがあり、こちらはマルチスレッドプログラムの評価も可能のようです。
Oprofileはデバッグ情報付きのvmlinuxが必要らしく、環境を作るのが面倒なので、もっと軽く動くという perf を使ってみました。
perfのプロファインリング情報(途中まで)
perfの測定結果をみると、gprofよりもバランスは良さそうです。
測定結果の情報には、コールグラフもあります。関数名がアドレス表示になっている箇所は、デバッグ情報付きカーネルを使用した時に関数名に変わるのかもしれません。
perfのコールグラフ情報情報(途中まで)
今回の性能改善には使用していませんが、マルチコアプログラミングでの動作を改善する方法がいくつかあります。
スレッド関数を特定のCPUコアに固定させて動かすことができます。
今回の課題では殆ど変化がありませんでしたが、パイプライン並列化処理に不均等なスレッドがあれば、コア指定が有効に使えそうです。
スレッド間の共有変数とスレッドローカルの変数が同じキャッシュラインに載ることにより、処理性能が大きく落ちることがあります。
本課題ではこれに該当する変数はありませんが、同じキャッシュラインに載らないようにするには、異なる用途の変数をキャッシュラインサイズの別区域に配置する必要があり、そのための指定を提供しているコンパイラもあります。
並列化処理の測定結果をまとめました。
表内の処理速度はいつも同じではありません。数回の動作から平均的な値を入れています。
並列化作業で感じたこと
並列処理プログラムのチューニング(改善作業)は、簡単ではありません。
とくにパイプライン並列化では、効果的なチューニング処理を見つけるのが難しそうです。せっかく手直ししても全く効果が無かったり、逆に性能が落ちてしまうこともあります。
本課題のようなごく簡単なプログラムなら何とかなりますが、実際に製品化されるような巨大なプログラムでは、チューニングを行うために役立つ情報を集められるか、そのためのツールが揃っているかが課題のように思います。
最後に、あたりまえのような内容ですが、並列化3種の使い道について無理やり書いてみました。
後日、情報を追加することがあるかもしれませんが、並列化処理の挑戦ブログはこれで終わりにします。
コメントをお書きください