BSD界隈四方山話

第85回DTraceの使い方 その5

プロセッサ: CPUとプロセス/スレッド

ps(1)やtop(1)を使うとどのプロセッサがどの程度使われているか、どのコアで実行されているのかを知ることができます。DTraceを使うとプロセッサごとにどのくらい使われているのか、どのプロセスがどのプロセッサでどの程度使われているのか、ということを調べることができます。コマンドではFreeBSDが提供しているライブラリやシステムコールを経由してこうしたデータを得ているのですが、DTraceではDTraceの機能でこうした情報を収集することができます。

次のDスクリプトは指定したプロセスに関して10秒間データを収集して、プロセッサ(論理コア)ごとにどの程度の時間実行されていたかを表示するものです。

リスト wrun.d
#!/usr/sbin/dtrace -s

#pragma D option quiet
inline int MAX = 10;

dtrace:::BEGIN
{
	start = timestamp;
}

sched:::on-cpu
/pid == $target/
{
	self->ts = timestamp;
}

sched:::off-cpu
/self->ts/
{
	@[cpu] = sum(timestamp - self->ts);
	self->ts = 0;
}

profile:::tick-1sec
/++x == MAX/
{
	exit(0);
}

dtrace:::END
{
	printf("\nCPU distribution over %d milliseconds:\n\n",
		(timestamp - start) / 1000000);
	printf("CPU microseconds\n--- ------------\n");
	normalize(@, 1000);
	printa("%3d %@d\n", @);
}

実行すると次のようにそれぞれの論理コアでどの程度プロセスが実行されていたのかを知ることができます。sched:::on-cpuとsched:::off-cpuでタイムスタンプを計測してその差分を加算していくことでこの計算を行っています。

 wrun.dの実行結果
# ./wrun.sh -p 38674 2> /dev/null

CPU distribution over 10007 milliseconds:

CPU microseconds
--- ------------
  1 93
  0 385
  2 522
  3 1735

#

次のDスクリプトは先ほどのwrun.dの内容を特定のプロセスに限定せずに、すべてのプロセス(スレッド)に対して計算して、プロセッサごとに1秒間あたりのプロセス/スレッドの平均実行時間、最大実行時間、最小実行時間を集計して出力したものです。

リスト lat.d
#!/usr/sbin/dtrace -s

#pragma D option quiet

sched:::enqueue
{
	s[args[0]->td_tid, args[1]->p_pid] = timestamp;
}

sched:::dequeue
/this->start = s[args[0]->td_tid, args[1]->p_pid]/
{
	this->time = timestamp - this->start;
	@lat_avg[cpu] = avg(this->time);
	@lat_max[cpu] = max(this->time);
	@lat_min[cpu] = min(this->time);
	s[args[0]->td_tid, args[1]->p_pid] = 0;
}

tick-1sec
{
	printf("%-8s %-12s %-12s %-12s\n",
		"CPU", "AVG(ns)", "MAX(ns)", "MIN(ns)");
	printa("%-8d %-@12d %-@12d %-@12d\n", 
		@lat_avg, @lat_max, @lat_min);
	trunc(@lat_avg);
	trunc(@lat_max);
	trunc(@lat_min);
}

実行すると次のような結果になります。Ctrl-Cで実行を終了させることができます。

 lat.dの実行結果
# ./lat.d 2> /dev/null
CPU      AVG(ns)      MAX(ns)      MIN(ns)
1        18385        18385        18385
3        29818        29818        29818
2        33541        33541        33541
CPU      AVG(ns)      MAX(ns)      MIN(ns)
1        27153        50187        4120
3        82593        82593        82593
2        206782       960847       3738
0        2311469      6928036      2883
CPU      AVG(ns)      MAX(ns)      MIN(ns)
2        3014         3014         3014
CPU      AVG(ns)      MAX(ns)      MIN(ns)
0        2759         2759         2759
CPU      AVG(ns)      MAX(ns)      MIN(ns)
1        1882         1882         1882
3        1958         2116         1800
2        4090         6465         2678
CPU      AVG(ns)      MAX(ns)      MIN(ns)
3        2088         2088         2088
1        2676         2676         2676
0        3285         3285         3285
2        14957        27360        2554
CPU      AVG(ns)      MAX(ns)      MIN(ns)
CPU      AVG(ns)      MAX(ns)      MIN(ns)
1        257785       257785       257785
0        1741312      3123997      358627
3        1837949      1837949      1837949
2        2422110      2422110      2422110

^C
#

lat.dの方ではDスクリプトの提供しているavg()、max()、min()を使っているあたりが見どころです。また、出力に関してprinta()を使っているあたりも押さえておきたいところです。処理がイベント駆動で動くようなものなので慣れないと動作を予測するのが難しいかもしれませんが、Dスクリプトはだいたいこんな感じで書いて使うことになります。

これと同じことをしようとした場合、同様のデータを得るためにシステムコールやライブラリの関数を実行してプログラムを組むわけですが、Dスクリプトを使うとそうしたことをせずにダイレクトに、しかも結構簡単に同じことが実現できます。いろんなところにホックが用意されているので結構自由にデータを取得できるあたりが強力なところです。

ここに掲載したサンプルスクリプトは"DTrace Dynamic Tracing In Oracle Solaris, Mac OS X & FreeBSD", by Brendan Gregg and Jim Mauro P.79およびP.81より抜粋したものです(FreeBSDで実行できるようにスクリプトの内容は書き換えてあります。実行結果もFreeBSDで実行した結果を掲載しています⁠⁠。

勉強会

第60回 2月23日(木)19:00~FreeBSD勉強会

発表内容検討中。発表ネタをお持ちの方、ぜひご連絡ください。

参加申請はこちらから。

第61回 3月23日(木)19:00~FreeBSD勉強会:リキャップ・ザ・AsiaBSDCon 2017~日本語でふりかえるABC~

2017年3月9~12日まで、東京でAsiaBSDCon 2017が開催される予定です。ぜひこのカンファレンスにご参加いただきたいわけなのですが、なかにはどうしても仕事の都合で参加できなかったとか、正直英語がよくわからなかったとか、そういった方もいらっしゃるのではないかと思います。

3月のFreeBSD勉強会では、AsiaBSDCon 2017のあとというこのタイミングを活かして、AsiaBSDCon 2017の発表内容を振り返ってみよう、というのをやってみようと思います。AsiaBSDConに参加しているにもかかわらず、これまで一度もプロシーディングを読み返したことすらないというあなた、ぜひプロシーディングを持参してご参加ください :) AsiaBSDConに参加できなかったというあなたも、この機会をお見逃しなく(できればAsiaBSDConそのものに参加した方が絶対的によいです、あしからず⁠⁠。

FreeBSD勉強会 発表者募集

FreeBSD勉強会では発表者を募集しています。FreeBSDに関して発表を行いたい場合、@daichigoto までメッセージをお願いします。1時間半〜2時間ほどの発表資料を作成していただき発表をお願いできればと思います。

おすすめ記事

記事・ニュース一覧