関数呼び出しにおける基本的な情報採取に関しては,
今回は,
マルチスレッド
マルチスレッド化によって性能や応答性の向上を実現するケースは,
特に近年は,
マルチスレッド稼動時の関数フロー
マルチスレッドで稼働中のプロセスから DTraceで関数フローを採取した場合,
各スレッドで,
リスト1 各スレッド上で実施される処理
void*
running(void* arg)
{
int loops = (int)arg;
int i;
for(i = 0 ; i < loops ; i += 1){
f3();
}
return NULL;
}
ループ内で呼び出している関数 f3()
については,
この処理を複数のスレッドで実行する際の関数フローを採取してみましょう。関数フロー採取には,watch_
スクリプトを使用します。
リスト2 関数フロー採取スクリプト
(watch_
)
pid$target:$1::entry,
pid$target:$1::return
{
}
5つのスレッドを並走させて採取された関数フローの例を,
リスト3 複数スレッドの関数フロー採取 ~ その1
CPU FUNCTION
0 -> _start
0 -> __fsr
0 <- __fsr
0 -> main
0 -> running
0 -> running
0 -> running
0 -> running
0 -> running
0 -> f3
0 -> f1
0 <- f1
0 -> f2
0 -> f1
0 <- f1
0 <- f2
0 <- f3
0 -> f3
0 -> f1
0 <- f1
0 -> f2
....
どの関数フローがどのスレッドで実行されたものか判別がつきませんね。
関数フローが複雑な場合や,
- ※1)
running()
関数のインデントが変になっているのは,複数スレッドで実行されている影響です。
スレッド識別情報の使用
マルチスレッド稼動時の DTrace 出力の問題点は,
しかし裏を返せば,
Dスクリプトで使用可能な組み込み変数には,tid
変数があります。リンク先の説明にもあるように,pthread_
呼び出し結果と同等の値を得ることができます。
それでは,tid
を併用して関数フローを採取してみましょう。
リスト4 スレッド識別情報の採取
pid$target:$1::entry,
pid$target:$1::return
{
printf("tid=%d", tid);
}
上記Dスクリプトは,entry
)return
)tid
の値を表示することで,
リスト 5 複数スレッドの関数フロー採取 ~ その2
CPU FUNCTION
0 -> _start tid=1
0 -> __fsr tid=1
0 <- __fsr tid=1
0 -> main tid=1
0 -> running tid=2
0 -> running tid=3
0 -> running tid=4
0 -> running tid=5
0 -> running tid=6
0 -> f3 tid=2
0 -> f1 tid=2
0 <- f1 tid=2
0 -> f2 tid=2
0 -> f1 tid=2
0 <- f1 tid=2
0 <- f2 tid=2
0 <- f3 tid=2
0 -> f3 tid=3
0 -> f1 tid=3
0 <- f1 tid=3
0 -> f2 tid=3
....
スレッド識別情報を表示することで,