CPU情報の詳細を探る
表1. ポイントと項目
No |
ポイント |
コマンドとオプション |
内容 |
@ |
プロセスアカウント情報の活用方法は? |
accton accountfile |
プロセスアカウント起動 |
accton |
プロセスアカウント停止 |
acctcom -f -m -t accountfile |
プロセスアカウント情報の編集 |
A |
コールの内訳はどうなっているのか?
【備考1】 |
truss -c [ -o tracefile ] -p PID |
PIDプロセスのコールサマリ出力 |
truss -c [ -o tracefile ] command ..... |
commandのコールサマリ出力 |
truss -f [ -o tracefile ] -p PID |
PIDプロセスの詳細トレース出力 |
truss -f [ -o tracefile ] command ..... |
commandの詳細トレース出力 |
truss -lDdaf [ -o tracefile ] -p PID |
PIDプロセスのより詳細なトレースを出力 |
truss -lDdaf [ -o tracdfile ] command ..... |
commandのより詳細なトレースを出力 |
sotruss [ -f ] [ -o tracefile ] command ...... |
ライブラリトレースの出力 |
apptrace [ -f ] [ -o tracefile ] command ..... |
アプリケーショントレースの出力 |
B |
ロック待ちの内訳はどうなっているのか? |
lockstat sleep 10 |
10秒間のロック情報を表示 |
lockstat -l lockname sleep 10 |
10秒間のlocknameで示す情報を表示 |
lockstat -kgIW |
プロファイルデータの表示 |
C |
コンテクストスイッチの内訳は? |
mpstat |
migr項目の確認 |
D |
ディスパッチャテーブルの内容は? |
dispadmin -l |
スケジューリングクラスの表示 |
dispadmin -c TS|RT -g > disp_table |
ディスパッチャテーブルの出力 |
dispadmin -c TS|RT -s disp_table |
ディスパッチャテーブルのセット |
E |
プライオリティを固定する方法は? |
dispadmin -c TS -d|-s |
ディスパッチャテーブルの出力とセット |
priocntl -s -p 59 -i pid PID |
-p 59にPIDを固定する |
F |
LWPの状態はどうなっているのか? |
ps -efcL |
LWP情報の表示 |
G |
カーネルコンポーネントの統計情報は? |
netstat -k |
カーネル統計情報の表示 |
kstat [module]:[instance]:[name]:[statistic] |
カーネル統計情報の表示(Solaris8以降) |
H |
カーネルコンポーネントの動きは? |
kgmon |
プロファイラの実行【備考2】 |
gprof gmon.syms gmon[n].out > kgmon_filen |
プロファイルデータの編集(CPU毎)【備考2】 |
prex |
カーネルトレーシングとTNFプルーブの操作 |
tnfxtract tracefile |
カーネルTNFプルーブの抜き出し |
tnfdump tracefile |
TNFファイルの編集 |
I |
CPUイベントの内訳は? |
cpustat -h |
イベント一覧を表示する |
cputrack -c eventspec command |
CPUイベントの表示 |
【備考】
1. |
プログラムのデバッグ段階では、GNUのgccによるgprof(プロファイラ)や、TNF(Trace Normal Form)プローブの埋め込みによるデバッグ手法を用いることが出来ます。本コンテンツでは解説を省略させていただきます。 |
2. |
kgmonはSolaris2.6までのコマンドです。Solaris7以降で無くなりました。かわりにlockstatコマンド-kgIWオプションが類似の出力を表示してくれます。 |
@プロセスアカウント情報の活用方法は?
プロセスアカウント情報は、CPU時間、プロセスサイズ、終了ステータス等を記録しています。acctcomコマンドは編集オプションをいくつか持っていますが、本コンテンツでは、-f、-m、および-tによって表示された情報を用いることにします。図1.1にその表示例、表1.1に表示情報の内容を解説します。
COMMAND |
|
|
START |
END |
REAL |
CPU |
(SECS) |
MEAN |
|
NAME |
USER |
TTYNAME |
TIME |
TIME |
(SECS) |
SYS |
USER |
SIZE(K) |
F |
STAT |
#accton |
root |
pts/2 |
17:03:16 |
17:03:16 |
0.01 |
0.00 |
0 |
920 |
42 |
0 |
echo |
root |
pts/2 |
17:03:16 |
17:03:16 |
0.02 |
0.01 |
0 |
1424 |
40 |
0 |
date |
root |
pts/2 |
17:03:16 |
17:03:16 |
0.01 |
0.00 |
0 |
920 |
40 |
0 |
nawk |
root |
pts/2 |
17:03:16 |
17:03:16 |
0.01 |
0.01 |
0 |
920 |
40 |
0 |
mkdir |
root |
pts/2 |
17:03:17 |
17:03:17 |
0.02 |
0.00 |
0 |
920 |
40 |
0 |
wc |
root |
pts/2 |
17:03:17 |
17:03:17 |
0.01 |
0.00 |
0 |
208 |
40 |
0 |
awk |
root |
pts/2 |
17:03:17 |
17:03:17 |
0.01 |
0.00 |
0 |
920 |
40 |
0 |
cat |
root |
pts/2 |
17:03:17 |
17:03:17 |
0.01 |
0.01 |
0 |
392 |
40 |
0 |
expr |
root |
pts/2 |
17:03:17 |
17:03:17 |
0.01 |
0.00 |
0 |
920 |
40 |
0 |
echo |
root |
pts/2 |
17:03:17 |
17:03:17 |
0.01 |
0.00 |
0 |
208 |
40 |
0 |
awk |
root |
pts/2 |
17:03:17 |
17:03:17 |
0.01 |
0.01 |
0 |
1224 |
40 |
0 |
date |
root |
pts/2 |
17:03:17 |
17:03:17 |
0.01 |
0.00 |
0 |
920 |
40 |
0 |
sed |
root |
pts/2 |
17:03:17 |
17:03:17 |
0.02 |
0.01 |
0 |
1656 |
40 |
0 |
echo |
root |
pts/2 |
17:03:17 |
17:03:17 |
0.01 |
0.00 |
0 |
920 |
40 |
0 |
#crash |
root |
pts/2 |
17:03:17 |
17:03:17 |
0.30 |
0.11 |
0.19 |
2129.6 |
42 |
0 |
|
図1.1 プロセスアカウントの出力(部分)
表1.1 プロセスアカウント情報の内容
項目 |
内容 |
COMMAND NAME |
コマンド名です。8文字に切り詰められます。ルートユーザから実行されるとコマンド名の先頭に"#"(シャープ)が付けられます。 |
USER |
コマンドを実行したユーザIDです。 |
TTYNAME |
コマンドを実行したTTY名です。 |
START TIME |
コマンドの開始時刻です。 |
END TIME |
コマンドの終了時刻です。終了時にプロセスアカウント情報が記録されます。 |
REAL(SECS) |
エラプス時間です。 |
CPU(SECS)SYS |
秒単位のシステムCPU時間です。 |
CPU(SECS)USER |
秒単位のユーザCPU時間です。 |
MEAN SIZE(K) |
推定のプロセスサイズです。mallocで獲得されたヒープや、スタック、共有メモリは反映されません。 |
F |
フラグです。通常0x00000028が10進数"40"で表示されます。SPREXECとSLOADを示します。
【参考】/usr/include/sys/proc.hをご覧下さい。 |
STAT |
戻り値です。通常"0"です。終了コード、またはシグナル番号がセットされます。 |
ちりも積もれば山になります。何気なく使用しているコマンドのシステムCPUやユーザCPU時間、それらがエラプス時間に占める割合を見ることで、より効率の良いコマンドや特徴をつかむことが出来ます。これには、情報採取区間内に実行されたコマンドを集計して、各コマンドのシステムとCPU時間、およびコマンド単体のシステムとCPU時間を求めます。図1.2に求め方を示します(図中、<CR>は省略しています)。
TIMEDIFF=300; export TIMEDIFF ←測定区間の時間を秒単位で指定します。
acctcom -f -m -t accountfile |
sed -n '5,$p' |
awk '{
cmd=sprintf("%s~%s",$1,$2)
elaps[cmd] = elaps[cmd] + $6
sys[cmd] = sys[cmd] + $7
user[cmd] = user[cmd] + $8
count[cmd] = count[cmd] + 1
}
END {
for ( proc in user) {
split(proc,array,"~")
printf"%-12s ",array[1]
printf"%-12s ",array[2]
printf"%15.2f ",elaps[proc]
printf"%14.0f ",count[proc]
printf"%12.2f ",sys[proc]+user[proc]
printf"%6.2f ",(sys[proc]+user[proc])/'"$TIMEDIFF"'*100
printf"%12.2f ",sys[proc]
printf"%12.4f ",sys[proc]/count[proc]*1000
printf"%12.2f ",user[proc]
printf"%12.4f\n",user[proc]/count[proc]*1000
}
}' > result |
図1.2 コマンドのCPU統計情報を求める
この出力をユーザCPUでソートした結果を図1.3に示します。ヘッダーは別に付け加えました。
command |
userid |
elaps |
callcount |
totalcpu |
rate% |
syscpu |
sysmsec |
usercpu |
usermsec |
w |
root |
174.96 |
10000 |
168.54 |
28.09 |
131.77 |
13.177 |
36.77 |
3.677 |
uptime |
root |
101.2 |
10000 |
55.09 |
9.18 |
34.75 |
3.475 |
20.34 |
2.034 |
add |
root |
201.29 |
20000 |
47.75 |
7.96 |
31.48 |
1.574 |
16.27 |
0.8135 |
expr |
root |
101.74 |
10087 |
28.24 |
4.71 |
16.8 |
1.6655 |
11.44 |
1.1341 |
average |
root |
100.51 |
10000 |
23.77 |
3.96 |
16.28 |
1.628 |
7.49 |
0.749 |
cpu12.sh |
root |
96.72 |
1 |
5.98 |
1 |
4.66 |
4660 |
1.32 |
1320 |
cpu11.sh |
root |
211.36 |
1 |
5.41 |
0.9 |
4.11 |
4110 |
1.3 |
1300 |
ps |
root |
4.83 |
140 |
2.95 |
0.49 |
1.68 |
12 |
1.27 |
9.0714 |
cpu13.sh |
root |
57.14 |
1 |
5.46 |
0.91 |
4.24 |
4240 |
1.22 |
1220 |
netstat |
root |
1213.36 |
245 |
2.17 |
0.36 |
1.22 |
4.9796 |
0.95 |
3.8776 |
pmap |
root |
3.08 |
156 |
2.98 |
0.5 |
2.22 |
14.2308 |
0.76 |
4.8718 |
sleep |
root |
2986.89 |
481 |
1.47 |
0.25 |
0.9 |
1.8711 |
0.57 |
1.185 |
echo |
root |
7.25 |
693 |
1.44 |
0.24 |
1.01 |
1.4574 |
0.43 |
0.6205 |
#crash |
root |
0.63 |
2 |
0.62 |
0.1 |
0.24 |
120 |
0.38 |
190 |
vmstat |
root |
1205.87 |
123 |
0.69 |
0.12 |
0.4 |
3.252 |
0.29 |
2.3577 |
sardo.sh |
root |
2431.48 |
8 |
1.11 |
0.18 |
0.82 |
102.5 |
0.29 |
36.25 |
awk |
root |
1.32 |
116 |
0.44 |
0.07 |
0.28 |
2.4138 |
0.16 |
1.3793 |
date |
root |
5.32 |
530 |
1.22 |
0.2 |
1.07 |
2.0189 |
0.15 |
0.283 |
cat |
root |
0.3 |
30 |
0.09 |
0.01 |
0.04 |
1.3333 |
0.05 |
1.6667 |
sed |
root |
0.28 |
26 |
0.06 |
0.01 |
0.02 |
0.7692 |
0.04 |
1.5385 |
uname |
root |
0.03 |
3 |
0.02 |
0 |
0 |
0 |
0.02 |
6.6667 |
swap |
root |
0.02 |
2 |
0.02 |
0 |
0 |
0 |
0.02 |
10 |
wc |
root |
0.04 |
4 |
0.01 |
0 |
0 |
0 |
0.01 |
2.5 |
nawk |
root |
0.31 |
31 |
0.1 |
0.02 |
0.09 |
2.9032 |
0.01 |
0.3226 |
kill |
root |
0.06 |
4 |
0.02 |
0 |
0.01 |
2.5 |
0.01 |
2.5 |
ipcs |
root |
0.02 |
2 |
0.02 |
0 |
0.01 |
5 |
0.01 |
5 |
sort |
root |
0.04 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
sadc |
root |
600 |
1 |
0.01 |
0 |
0.01 |
10 |
0 |
0 |
rm |
root |
0.08 |
4 |
0 |
0 |
0 |
0 |
0 |
0 |
pwd |
root |
0.05 |
5 |
0.04 |
0.01 |
0.04 |
8 |
0 |
0 |
mv |
root |
0.03 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
mkdir |
root |
0.1 |
4 |
0.01 |
0 |
0.01 |
2.5 |
0 |
0 |
iostat |
root |
600.08 |
1 |
0.01 |
0 |
0.01 |
10 |
0 |
0 |
id |
root |
0.01 |
1 |
0.01 |
0 |
0.01 |
10 |
0 |
0 |
df |
root |
0.02 |
2 |
0 |
0 |
0 |
0 |
0 |
0 |
#sendmail |
root |
0.01 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
#mpstat |
root |
601.12 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
|
図1.3 コマンドのCPU統計情報
ヘッダー項目の内容を表1.2に示します。
表1.2 プロセスアカウント統計情報の内容
項目 |
内容 |
command |
コマンド名です。 |
userid |
ユーザIDです。 |
elaps |
エラプス時間の合計秒です。 |
callcount |
当該コマンドのコール回数です。 |
totalcpu |
CPU時間の合計秒です。 |
rate% |
測定時間全体に占めるCPU時間の割合です。CPUが複数ある場合、枚数分で割り算して下さい。 |
syscpu |
システムCPUの秒です。 |
sysmsec |
コマンド1回あたりのシステムCPUミリ秒です。 |
usercpu |
ユーザCPUの秒です。 |
usermsec |
コマンド1回あたりのユーザCPUミリ秒です。 |
このようにして、各種コマンドの特徴を、システムCPU時間が高い、ユーザCPU時間が高い、あるいはエラプス時間に対してCPU消費が少ない…何らかの待ちやディスク入出力が多いことを意味します…等をつかみ、改善できるものがあれば改修することが出来ます。
Aコールの内訳はどうなっているのか?
リード・ライト、exec/fork、IPC関連システムコールの発行量、程度はsarコマンドで知ることが出来ます。一方、そのシステムコールを誰が実行したのか、またはその他のシステムコールはどの程度発行されているのかはsarコマンドだけでは分かりません。少なくともプロセスのあたりをつけ、そのプロセスがどのようなシステムコールをどの程度発行したのかを知るためのコマンドがtrussです。まず、コマンドのサマリをtrussコマンド-cオプションで調べてみましょう。
# ps -efl | grep ckpt <CR> |
|
|
8 S oracle |
563 1 1 51 |
20 ? |
53304 ? |
18:29:23 |
? 0 |
:00 |
ora_ckpt_ora900 |
|
|
# truss -c -p 563 <CR> |
|
|
syscall |
seconds |
calls |
errors |
_exit |
0 |
1 |
|
write |
0.01 |
53 |
|
close |
0 |
7 |
|
creat |
0 |
1 |
|
stat |
0 |
2 |
1 |
getpid |
0 |
2 |
|
kill |
0 |
8 |
|
shmdt |
0 |
1 |
|
semctl |
0.02 |
222 |
|
semtimedop |
0.01 |
316 |
153 |
fcntl |
0 |
3 |
|
sigprocmask |
0 |
2 |
|
sigaction |
0.01 |
19 |
|
yield |
0 |
30 |
|
lwp_cond_wait |
0.02 |
459 |
|
lwp_cond_signal |
0.04 |
459 |
|
llseek |
0 |
1 |
|
kaio |
0.12 |
3931 |
3931 |
pread64 |
0 |
48 |
|
pwrite64 |
0 |
459 |
|
|
------- |
------ |
---- |
sys totals: |
0.23 |
6024 |
4085 |
|
|
usr time: |
0.64 |
|
|
elapsed: |
479.81 |
|
|
# |
|
|
|
|
図2.1 trussコマンド-cオプションによるコールサマリ
ORACLEのチェックポイントプロセスをトレースしたものです。trussコマンドはそのプロセスが終了した時に同時に終了し、図2.1にあるサマリを表示します。オプション-p
PIDのかわりに、調査したいコマンドをそのまま指定しても良いです。通常、プロセスの開始処理でファイルオープンしたりすることが多いので、-p
PIDでは途中からのトレースになります。プロセスの処理開始から終了までの全コール情報を得たい場合は、trussコマンドの実行と同時に、調査したいコマンドを起動する必要があります。図2.1の例では発行したシステムコール、回数、エラーの有無が表示されています。sys
totals:はシステムCPU時間、usr time:はユーザCPU時間で、elapsed:に実行時間が表示されています。単位は秒です。この中から、問題となっている部分を確認し、対処します。
trussコマンド-fオプションは詳細なトレース情報を表示します。次にechoコマンドのトレース出力例を示します。
# truss -f echo A <CR> |
|
5606: |
execve("/usr/bin/echo", 0xFFBEFEC4, 0xFFBEFED0)argc = 2 |
5606: |
mmap(0x00000000, 8192, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANON, -1, 0) = 0xFF3A0000 |
5606: |
resolvepath("/usr/lib/ld.so.1", "/usr/lib/ld.so.1",
1023)= 16 |
5606: |
open("/var/ld/ld.config", O_RDONLY) Err#2 ENOENT= 3 |
5606: |
open("/usr/lib/libc.so.1", O_RDONLY)= 0 |
5606: |
fstat(3, 0xFFBEF5FC) |
5606: |
mmap(0x00000000, 8192, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0xFF390000 |
5606: |
mmap(0x00000000, 794624, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0xFF280000 |
5606: |
mmap(0xFF33A000, 24692, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 696320) = 0xFF33A000 |
5606: |
munmap(0xFF32A000, 65536)= 0 |
5606: |
memcntl(0xFF280000, 113380, MC_ADVISE, MADV_WILLNEED, 0, 0)= 0 |
5606: |
close(3)= 0 |
5606: |
open("/usr/lib/libdl.so.1", O_RDONLY)= 3 |
5606: |
fstat(3, 0xFFBEF5FC)= 0 |
5606: |
mmap(0xFF390000, 8192, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) = 0xFF390000 |
5606: |
close(3)= 0 |
5606: |
open("/usr/platform/SUNW,Sun-Blade-1000/lib/libc_psr.so.1", O_RDONLY)=
3 |
5606: |
fstat(3, 0xFFBEF48C)= 0 |
5606: |
mmap(0x00000000, 8192, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0xFF380000 |
5606: |
close(3)= 0 |
5606: |
ioctl(1, TCGETA, 0xFFBEFBB4)= 0 |
A |
5606: |
write(1, " A\n", 2)= 2 |
5606: |
llseek(0, 0, SEEK_CUR)= 3847 |
5606: |
_exit(0) |
# |
|
図2.2 ftrssコマンド-fオプションのトレース
trussコマンド-fオプションは大量にトレース情報を出力します。トレース情報表示のため、本体コマンドの実行は遅くなります。このことは、trussコマンドは時間的な関係を知るためには不向きで、ロジック上の動作確認のために使用することがポイントと考えます。なお参考文献2はtrussコマンドの-lDdafオプションがお勧めになっています。LWPや時間スタンプが詳細に出力されます。出力例を次に示します。
# truss -lDdaf echo A <CR> |
Base time stamp: |
1089627919 |
.9242 |
[ Mon Jul 12 19:25:19 JST 2004 ] |
5610/1: |
0.0000 |
0.0000 |
execve("/usr/bin/echo", 0xFFBEFEC4, 0xFFBEFED0) argc = 2 |
5610/1: |
argv: |
echoA |
|
5610/1: |
0.2242 |
0.2242 |
mmap(0x00000000, 8192, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANON, -1, 0) = 0xFF3A0000 |
5610/1: |
0.2244 |
0.0002 |
resolvepath("/usr/lib/ld.so.1", "/usr/lib/ld.so.1", 1023) = 16 |
5610/1: |
0.2246 |
0.0002 |
open("/var/ld/ld.config", O_RDONLY) Err#2 ENOENT |
5610/1: |
0.2248 |
0.0002 |
open("/usr/lib/libc.so.1", O_RDONLY)= 3 |
5610/1: |
0.2249 |
0.0001 |
fstat(3, 0xFFBEF5FC)= 0 |
5610/1: |
0.2250 |
0.0001 |
mmap(0x00000000, 8192, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0xFF390000 |
5610/1: |
0.2251 |
0.0001 |
mmap(0x00000000, 794624, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0xFF280000 |
5610/1: |
0.2252 |
0.0001 |
mmap(0xFF33A000, 24692, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 696320) = 0xFF33A000 |
5610/1: |
0.2254 |
0.0002 |
munmap(0xFF32A000, 65536)= 0 |
5610/1: |
0.2257 |
0.0003 |
memcntl(0xFF280000, 113380, MC_ADVISE, MADV_WILLNEED, 0, 0) = 0 |
5610/1: |
0.2258 |
0.0001 |
close(3)= 0 |
5610/1: |
0.2259 |
0.0001 |
open("/usr/lib/libdl.so.1", O_RDONLY)= 3 |
5610/1: |
0.2260 |
0.0001 |
fstat(3, 0xFFBEF5FC)= 0 |
5610/1: |
0.2261 |
0.0001 |
mmap(0xFF390000, 8192, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) = 0xFF390000 |
5610/1: |
0.2263 |
0.0002 |
close(3)= 0 |
5610/1: |
0.2264 |
0.0001 |
open("/usr/platform/SUNW,Sun-Blade-1000/lib/libc_psr.so.1", O_RDONLY) = 3 |
5610/1: |
0.2266 |
0.0002 |
fstat(3, 0xFFBEF48C)= 0 |
5610/1: |
0.2266 |
0.0000 |
mmap(0x00000000, 8192, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0xFF380000 |
5610/1: |
0.2268 |
0.0002 |
close(3)= 0 |
5610/1: |
0.2276 |
0.0008 |
ioctl(1, TCGETA, 0xFFBEFBB4)= 0 |
A |
|
|
|
5610/1: |
0.2278 |
0.0002 |
write(1, " A\n", 2)= 2 |
5610/1: |
0.2279 |
0.0001 |
llseek(0, 0, SEEK_CUR)= 5708 |
5610/1: |
0.2280 |
0.0001 |
_exit(0) |
# |
|
|
|
|
図2.3 trussコマンド-lDdafオプションのトレース
sotrussコマンドはSolaris8から提供された共用ライブラリコールをトレースするコマンドです。
# sotruss -f date <CR> |
18012:date |
-> |
libc.so.1:*atexit(0xff3bc558,0x21800,0x0) |
18012:date |
-> |
libc.so.1:*atexit(0x115cc,0xff23a004,0xff3bc558) |
18012:date |
-> |
libc.so.1:*setlocale(0x6,0x11624,0xff23c5a8) |
18012:date |
-> |
libc.so.1:*textdomain(0x11628,0xff23d9fc,0xff23a004) |
18012:date |
-> |
libc.so.1:*getopt(0x1,0xffbefdcc,0x11638) |
18012:date |
-> |
libc.so.1:*time(0x21cbc,0xffffffff,0xff23cc48) |
18012:date |
-> |
libc.so.1:*nl_langinfo(0x3a,0xffffffff,0x21cbc) |
18012:date |
-> |
libc.so.1:*localtime(0x21cbc,0x3a,0xff23a004) |
18012:date |
-> |
libc_psr.so.1:*memcpy(0xffbefd3c,0xff240988,0x24) |
18012:date |
-> |
libc.so.1:*strftime(0x21cc0,0x400,0xff227f14) |
18012:date |
-> |
libc.so.1:*puts(0x21cc0,0x400,0x21cc0) |
Tue Jul 13 |
17:54:50 |
JST 2004 |
18012:date |
-> |
libc.so.1:*exit(0x0,0xff227f14,0xffbefdd4) |
# |
|
|
図2.4 sotrussコマンドの出力
Bロック待ちの内訳はどうなっているのか?
マルチスレッド環境で、メモリ空間を共用して更新する際、ミューテックスロックと呼ばれる機構を用いてメモリ内容の一貫性を保っています。メモリのある領域を更新中、他のスレッドが同じ領域を更新するのを防ぐわけです。CPUが一個でも複数でも仕組みは同じです。ロック待ちが亢進すると資源の充分な活用が図れません。lockstatコマンドは、引数にsleepで休眠(採取)時間を指定し、その時間内に幾つのロックがどの程度発生していたかを収集するコマンドです。
# lockstat sleep 10 <CR> |
|
|
|
|
|
|
|
Adaptive |
muex |
block:3 mutex |
events |
10.064 |
seconds |
(0 events/sec) |
|
|
|
|
|
|
|
Count |
indv |
cuml |
rcnt |
nsec |
Lock |
Caller |
------- |
------- |
----------- |
----- |
-------- |
------------- |
------------ |
1 |
33% |
33% |
1.00 |
19200 |
0x30001f429f8 |
putnext+0x54 |
1 |
33% |
67% |
1.00 |
45296800 |
0x300010780e0 |
alloccg+0x11c |
1 |
33% |
100% |
1.00 |
21400 |
0x3000005eda0 |
ssdintr+0x38 |
------- |
------- |
----------- |
----- |
-------- |
------------- |
------------ |
# |
|
|
|
|
|
|
|
図3.1 ロックの調査
この例は、UFS(UNIXファイルシステム)のcg(シリンダーグループ)を割当てる関数alloccgのところで、約45ミリ秒待ったことがわかります。-lオプションを指定し、Callerにあるイベントを引数に指定することでより絞り込んだステータスを表示することが出来ます(-lオプションの適切な例を作ることができませんでした。弊社のテスト環境がシングルCPUなので、かなり難しいことでした。すいません…)。次の図は、Solaris8からの新たなlockstat機能で、kgmonの代わりとなるオプションの表示例です。
# lockstat -kgIW sleep 5 <CR> |
Profiling |
interrupt: |
485 events |
in 5.001 |
sedonds |
(97 events/sec) |
|
|
Count |
genr |
cuml |
rcnt |
nsec |
Hottest |
CPU+PIL |
Caller |
------------------------------------------------------------------------------- |
892 |
184% |
---- |
1.00 |
1000 |
cpu[0] |
|
idle |
485 |
100% |
---- |
1.00 |
1021 |
cpu[0] |
|
lockstat_intr |
485 |
100% |
---- |
1.00 |
1021 |
cpu[0] |
|
cyclic_fire |
485 |
100% |
---- |
1.00 |
1021 |
cpu[0] |
|
cbe_level14 |
485 |
100% |
---- |
1.00 |
1021 |
cpu[0] |
|
current_thread |
482 |
99% |
---- |
1.00 |
1000 |
cpu[0] |
|
thread_start |
19 |
4% |
---- |
1.00 |
920 |
cpu[0] |
|
generic_idle_cpu |
2 |
0% |
---- |
1.00 |
4112 |
cpu[0] |
|
fifo_poll |
2 |
0% |
---- |
1.00 |
4489 |
cpu[0] |
|
fsflush |
1 |
0% |
---- |
1.00 |
4112 |
cpu[0] |
|
pcache_poll |
1 |
0% |
---- |
1.00 |
4112 |
cpu[0] |
|
poll |
1 |
0% |
---- |
1.00 |
4150 |
cpu[0] |
|
page_trylock |
1 |
0% |
---- |
1.00 |
4828 |
cpu[0] |
|
mutex_exit |
1 |
0% |
---- |
1.00 |
4150 |
cpu[0] |
|
mutex_enter |
------------------------------------------------------------------------------- |
# |
|
|
|
|
|
|
|
|
図3.2 プロファイルデータの表示
Cコンテクストスイッチの内訳は?
コンテクストスイッチはユーザモードからカーネルモード、またはその逆の動作の総称です。コンテクストは大きく実行コンテクストと仮想メモリコンテクストに分けられます。実行コンテクストはプロセス、割り込み、カーネルの3種類に分けられます。仮想メモリコンテクストは、スケジューラが、あるプロセスから別プロセスに実行を切り替える時、割り込みやトラップによってユーザモードからカーネルモードへ切り替わる時等に、メモリアドレスを変換する処理として実行されます。
(1)より高い優先度のスレッドに制御を横取り(preemption)された時。
(2)スレッドがCPU使用可能時間(ディスパッチャテーブルの解説で後述します)を使い果たした時。
(3)システムコールを発行した時やその処理待ち時。
(1)と(2)は非自発的コンテクストスイッチ、(3)は自発的コンテクストスイッチと呼ばれます。
コンテクストスイッチの秒あたりの発生回数は、sarコマンド-wオプションで表示されるpswch/s、またはvmstatコマンドのcsです。これらの値はシステム全体の発生量を示しています。mpstatコマンドのithr、csw、icsw、およびmigrはCPU毎のコンテクストスイッチを表示してくれます。ithrは割り込んだスレッドの数(クロック割り込みは含みません)、cswはsarコマンドのpswch/sや、vmstatのcsと同様のコンテクストスイッチです。mpstatのicswは非自発的コンテクストスイッチを表します(無作為コンテクストスイッチとも呼ばれます)。migrは他のCPU(またはスレッド)に制御が移ったことを表します。仮想メモリコンテクストが含まれることがあります。なんだか文章では分かりにくいので、一覧表にしました。
表4.mpstatのコンテクスト項目
項目 |
計数モジュール【備考】 |
関数名 |
きっかけ |
値の足し算の仕方 |
ithr |
uts/sun4u/ml/interrupt.s |
intr_thread |
割り込み |
CPU_SYSINFO_INTRTHREADの値をプラス(inc)。 |
csw |
uts/common/disp/disp.c |
swtch
swtch_to
swtch_from_zombie |
ディスパッチ |
CPU_STAT_ADDQマクロを使用して、cpu_sysinfo.pswitchの値をプラス。 |
icsw |
uts/common/disp/disp.c |
preempt |
横取り |
CPU_STAT_ADDQマクロを使用して、cpu_sysinfo.inv_swtchの値をプラス。 |
uts/common/syscall/yield.c |
yield |
システムコール |
同上。 |
migr |
uts/sun4u/ml/swtch.s |
resume |
スレッド切り換え |
CPU_SYSINFO_CPUMIGRATEの値をプラス(inc)。 |
【備考】sun4uのディレクトリ名はハードウェアアーキテクチャによって変わります。
これらのことから、システムコールが多く発行された、割り込みが多発した、あるいは実行可能なスレッドが数多くあると、コンテクストスイッチの値が高まることが分かります。
Dディスパッチャテーブルの内容は?
ディスパッチャテーブルはRT(リアルタイム)、SYS(システム)、およびTS(タイムシェアリング)のクラスにわけられています。これらの全部をグローバル優先度として管理します。値が大きいと優先度が高いことを示しています。表5.1にその関係を示します。
表5.1 スケジューリングクラス
グローバル優先度の範囲 |
クラス名 |
対象 |
100〜159 |
RT |
リアルタイムクラス。システムでもっとも優先度の高いクラスです。グローバル優先度100〜109は割り込みスレッドです。 |
60〜99 |
SYS |
システムクラスです。 |
0〜59 |
TS/IA |
一般の優先度であるタイムシェアリング、または対話型クラスです。 |
このディスパッチャテーブルの内容を表示・書き込みするコマンドがdispadminです。dispadminコマンド-lオプションは、構成されているクラスの一覧表を表示します。この構成一覧から目的のディスパッチャーテーブルを選択します。実際に設定可能なディスパッチャテーブルは、TSのタイムシェアリングクラスのみです。RT(リアルタイム)のディスパッチャテーブルは調整しない方が良いでしょう。チューニングの方法は、dispadminコマンドで表示されたテーブルの内容を変更して、同じくdispadminコマンドで書き込み、ディスパッチャのプロセス(スレッド)優先度の動作を変化させるというものです。よく行うチューニングは、ts_quantumの値や、次に移されるプライオリティレベルを変更する方法です(あまり一般的ではありませんが、他のUNIXシステムのディスパッチャテーブルはSolarisのものと大きな違いがあります)。
# dispadmin -l CR>
CONFIGURED CLASSES
===================
SYS (System Class)
TS (Time Sharing)
RT (Real Time)
IA (Interactive)
# dispadmin -c TS -g <CR>
# Time |
Sharing |
Dispatcher |
Configuration |
|
|
|
RES=1000 |
|
|
|
|
|
|
|
|
|
|
|
|
|
# ts_quantum |
ts_tqexp |
ts_slpret |
ts_maxwait |
ts_lwait |
PRIORITY |
LEVEL |
200 |
0 |
50 |
0 |
50 |
# |
0 |
200 |
0 |
50 |
0 |
50 |
# |
1 |
|
|
|
: |
|
|
|
200 |
0 |
50 |
0 |
50 |
# |
8 |
200 |
0 |
50 |
0 |
50 |
# |
9 |
160 |
0 |
51 |
0 |
51 |
# |
10 |
160 |
1 |
51 |
0 |
51 |
# |
11 |
|
|
|
: |
|
|
|
160 |
8 |
51 |
0 |
51 |
# |
18 |
160 |
9 |
51 |
0 |
51 |
# |
19 |
120 |
10 |
52 |
0 |
52 |
# |
20 |
120 |
11 |
52 |
0 |
52 |
# |
21 |
|
|
|
: |
|
|
|
120 |
18 |
52 |
0 |
52 |
# |
28 |
120 |
19 |
52 |
0 |
52 |
# |
29 |
80 |
20 |
53 |
0 |
53 |
# |
30 |
80 |
21 |
53 |
0 |
53 |
# |
31 |
|
|
|
: |
|
|
|
80 |
28 |
54 |
0 |
54 |
# |
38 |
80 |
29 |
54 |
0 |
54 |
# |
39 |
40 |
30 |
55 |
0 |
55 |
# |
40 |
40 |
31 |
55 |
0 |
55 |
# |
41 |
|
|
|
: |
|
|
|
40 |
47 |
58 |
0 |
59 |
# |
57 |
40 |
48 |
58 |
0 |
59 |
# |
58 |
20 |
49 |
59 |
32000 |
59 |
# |
59 |
# |
図5.TSディスパッチャテーブルの内容(抜粋)
表5.2 ディスパッチャテーブルの内容
項目 |
内容 |
RES |
秒あたりのレゾリューションで、1000の場合は1ミリ秒がその解像度になります。項目ts_quantumとts_maxwaitの単位になります。 |
ts_quantum |
この間、タイムシェアリングプロセス(スレッド)は中断しないで実行が許されます。このタイムクォンタムを使い切るとts_toexpに設定された優先度に置かれます。 |
ts_toexp |
ts_quantmを使い切るとそのプロセス(スレッド)が次ぎに移される優先度です。 |
ts_slpret |
プロセスがts_quantumを使い切る前に自分自身が入出力やその他のスリープに移った時、そのプロセス(スレッド)に割り当てられる優先度を示します。 |
ts_maxwait |
このレベルで実行されているプロセス(スレッド)が使うことを許される最大の時間です。 |
ts_lwait |
ts_maxwaitを経過すると次に割り当てられる優先度です。 |
PRIORITY LEVEL |
プライオリティのレベルです。高い値ほど優先度が高いことを示しています。 |
Eプライオリティを固定する方法は?
参考文献2の「ディスパッチテーブルをチューニングする」、「優先度を調整する」の「TSクラスの優先度を囲い込む(fence
off)方法」に手順が記述されていますのでご覧下さい。本コンテンツでは解説を省略させていただきます。
FLWPの状態はどうなっているのか?
psコマンド-efcLオプションを使用すると、LWP(ライトウェイトプロセス)単位の状態を見ることができます。項目LWPはスレッドの番号、NLWPはそのプロセスの合計スレッド数を示しています。
# ps -efcL <CR>
UID |
PID |
PPID |
LWP |
NLWP |
CLS |
PRI |
STIME |
TTY |
LTIME |
CMD |
root |
0 |
0 |
1 |
1 |
SYS |
96 |
12:04:59 |
? |
0:01 |
sched |
root |
1 |
0 |
1 |
1 |
TS |
58 |
12:05:00 |
? |
0:04 |
/etc/init - |
root |
2 |
0 |
1 |
1 |
SYS |
98 |
12:05:00 |
? |
0:00 |
pageout |
root |
3 |
0 |
1 |
1 |
SYS |
60 |
12:05:00 |
? |
0:52 |
fsflush |
root |
73 |
1 |
1 |
7 |
TS |
59 |
12:05:14 |
? |
0:00 |
devfsadmd |
|
|
|
|
|
|
|
: |
|
|
root |
73 |
1 |
8 |
7 |
TS |
59 |
12:05:16 |
? |
0:00 |
devfsadmd |
|
|
|
|
|
|
|
: |
|
|
root |
335 |
333 |
1 |
5 |
TS |
43 |
12:05:28 |
? |
0:00 |
htt_server -port 9010 -syslog -message_locale C |
|
|
|
|
|
|
|
: |
|
|
root |
335 |
333 |
5 |
5 |
TS |
53 |
12:05:29 |
? |
0:00 |
htt_server -port 9010 -syslog -message_locale C |
root |
354 |
1 |
1 |
1 |
TS |
58 |
12:05:31 |
? |
0:00 |
/usr/lib/locale/ja/atokserver/atokmngdaemon |
root |
388 |
1 |
1 |
1 |
TS |
55 |
12:05:33 |
? |
0:00 |
/opt/SUNWspci2/bin/sunpcid |
daemon |
348 |
1 |
1 |
3 |
TS |
32 |
12:05:30 |
? |
0:00 |
/usr/lib/ab2/dweb/sunos5/bin/dwhttpd /usr/lib/ab2/dweb/data |
|
|
|
|
|
|
|
: |
|
|
daemon |
349 |
348 |
4 |
4 |
TS |
59 |
12:05:30 |
? |
0:00 |
/usr/lib/ab2/dweb/sunos5/bin/dwhttpd /usr/lib/ab2/dweb/data |
|
|
|
|
|
|
|
: |
|
|
oracle |
445 |
1 |
1 |
1 |
TS |
59 |
12:07:53 |
? |
0:00 |
ora_pmon_ora900 |
oracle |
447 |
1 |
1 |
16 |
TS |
59 |
12:07:53 |
? |
0:00 |
ora_dbw0_ora900 |
|
|
|
|
|
|
|
: |
|
|
oracle |
447 |
1 |
16 |
16 |
TS |
60 |
12:39:06 |
? |
0:00 |
ora_dbw0_ora900 |
oracle |
449 |
1 |
1 |
11 |
TS |
59 |
12:07:53 |
? |
0:00 |
ora_lgwr_ora900 |
|
|
|
|
|
|
|
: |
|
|
oracle |
449 |
1 |
11 |
11 |
TS |
58 |
12:08:01 |
? |
0:00 |
ora_lgwr_ora900 |
oracle |
451 |
1 |
1 |
11 |
TS |
58 |
12:07:53 |
? |
0:52 |
ora_ckpt_ora900 |
|
|
|
|
|
|
|
: |
|
|
oracle |
451 |
1 |
11 |
11 |
TS |
58 |
12:08:03 |
? |
0:00 |
ora_ckpt_ora900 |
oracle |
453 |
1 |
1 |
1 |
TS |
58 |
12:07:53 |
? |
0:01 |
ora_smon_ora900 |
oracle |
455 |
1 |
1 |
1 |
TS |
58 |
12:07:53 |
? |
0:00 |
ora_reco_ora900 |
oracle |
457 |
1 |
1 |
1 |
TS |
59 |
12:07:53 |
? |
0:00 |
ora_cjq0_ora900 |
oracle |
459 |
1 |
1 |
1 |
TS |
59 |
12:07:53 |
? |
0:00 |
ora_s000_ora900 |
oracle |
461 |
1 |
1 |
1 |
TS |
59 |
12:07:54 |
? |
0:00 |
ora_d000_ora900 |
oracle |
463 |
1 |
1 |
1 |
TS |
59 |
12:07:54 |
? |
0:00 |
ora_d001_ora900 |
oracle |
465 |
1 |
1 |
1 |
TS |
59 |
12:07:54 |
? |
0:00 |
ora_d002_ora900 |
# |
図7.psコマンド-efcLオプション(抜粋)
Gカーネルコンポーネントの統計情報は?
Solaris 8以降ではkstatコマンド【備考1】、全てのSolarisレベルではnetstatコマンド-kオプション【備考2】でさまざまなカーネルコンポーネントの統計情報を出力することが出来ます。kstatの引数無し、およびnetstatコマンド-kオプションも大量の情報が出ますので、一旦ファイルに書き込んでから参照されると良いでしょう。kstatはモジュール、インスタンス、名前等を指定することで目的の統計情報を選択出来るようになっています。次に例を示します。
kstatコマンドによるIPCセマフォの統計情報 |
netstatコマンド -kオプションで出力したIPCセマフォの統計情報 |
# kstat vme:39:semaphore <CR> |
module: |
vmem |
instance: |
39 |
name: |
semaphore |
class: |
vmem |
|
alloc |
4 |
|
contains |
0 |
|
contains_search |
0 |
|
crtime |
225.3602432 |
|
fail |
0 |
|
free |
3 |
|
lookup |
0 |
|
mem_import |
0 |
|
mem_inuse |
154 |
|
mem_total |
1024 |
|
populate_fail |
0 |
|
populate_wait |
0 |
|
search |
8 |
|
snaptime |
16892.09894 |
|
vmem_source |
0 |
|
wait |
0 |
# |
|
|
# netstat -k | tail -5 <CR>
semaphore:
mem_inuse 154 mem_import 0 mem_total 1024 vmem_source 0 alloc 4
free 3 wait 0 fail 0 lookup 0 search 8 populate_wait 0
populate_fail 0 contains 0 contains_search 0
# |
【備考】
1. |
kstatコマンドはperlスクリプトです。興味のある方はエディタでご覧下さい。 |
2. |
将来にわたってnetstatコマンド-kオプションの出力は保証されないとベンダーは言っています。困った… |
図8.カーネルコンポーネントの統計情報
Hカーネルコンポーネントの動きは?
カーネルの詳細な動きを調べてみます。コマンドはSolaris2.6以前とSolaris8以降に違いがあります。最初にSolaris2.6のkgmon/gprofを紹介します。
Solaris2.6カーネルプロファイラ
次のようにkgmonコマンドでカーネルプロファイラを起動し、gprofによって情報を編集します。
# kgmon -i <CR>
one moment
disabling module unloading.
NOTE:modules loaded after this point will not be profiled.
profiling has been initialized
WARNING:call graph profiling is not compiled into this kernel
WARNING:only clock sample profiling is available
# kgmon -b <CR>
kernel profiling for cpu 1, is running【備考】
[[ この間にプロセスやトランザクションを実行します。 ]]
# kgmon -h <CR>
kernel profiling for cpu 1, is off
# kgmon -p <CR>
dumping cpu 1 - one moment
a.out symbols for the kernel and modules have been dumped to gmon.syms
profiling data has been dumped to gmon[n].out
# /usr/ccs/bin/gprof gmon.syms gmon1.out > cpu1profile <CR>
#
【備考】CPUが32個以上のシステムでは採取できませんでした(経験的情報です)。 |
図9.1 Solaris2.6カーネルプロファイラ
次はプロファイラの出力例(抜粋)です。なお、各ファンクションのアルファベット順インデックスは省略させていただきます。
granularity: each sample hit covers 2 byte(s) for 0.05% of 23.75 seconds |
% |
cumulative |
self |
|
self |
total |
|
time |
seconds |
seconds |
calls |
ms/call |
ms/call |
name |
|
24.7 |
|
5.86 |
|
5.86 |
splx[1] |
|
23.5 |
|
11.43 |
|
5.57 |
disp_getwork[2] |
|
13.8 |
|
14.71 |
|
3.28 |
idle[3] |
|
11.2 |
|
1738 |
|
2.67 |
spltty[4] |
|
3.1 |
|
18.12 |
|
0.75 |
spl0[5] |
|
2.2 |
|
18.64 |
|
0.52 |
splzs[6] |
|
2.1 |
|
19.13 |
|
0.49 |
diap_ratify[7] |
|
1.3 |
|
19.43 |
|
0.6 |
bcopy[8] |
|
1.1 |
|
19.99 |
|
0.27 |
sfmmutteload_addentry[9] |
|
0.7 |
|
20.13 |
|
0.18 |
mutex_enter[10] |
|
0.7 |
|
20.18 |
|
0.15 |
hwblkclr[11] |
|
図9.2 kgmon/gprofプロファイラの出力例
続いてSolaris8のカーネルトレースを紹介します。
Solaris8カーネルトレース
次のように、prexコマンドでトレースをセットし、tnfxtractコマンドでデータを抽出、tnfdumpコマンドで編集します。prexの解説はprex(1)カーネルトレースをご覧下さい。
# prex -k <CR>
Type "help" for help ...
prex> buffer alloc 4m <CR>
Buffer of size 4194304 bytes allocated
prex> enable $all <CR>
prex> trace $all <CR>
prex> ktrace on <CR>
: この間にトレースしたい処理を実行します。
prex> ktrace off <CR>
prex> quit <CR>
# tnfxtract tracefile.trc <CR>
# tnfdump tracefile.trc > tracefile.dump <CR>
# |
図9.3 カーネルトレース
次にtnfdumpコマンドの出力例を示します(抜粋)。
---------- |
--------- |
----- |
---- |
----- |
------ |
------------ |
------ |
------------ |
---- |
----------- |
------ |
-- |
---------- |
Elapsed(ms) |
Delta(ms) |
PID |
LWPID |
TID |
CPU |
Probe Name |
Data |
|
/ |
Description |
|
|
|
---------- |
--------- |
----- |
---- |
----- |
------ |
------------ |
------ |
------------ |
---- |
----------- |
------ |
-- |
---------- |
0 |
0 |
435 |
1 |
0x300 |
0 |
syscall_end |
rval1: |
0 |
rval2: |
4 |
errno: |
0 |
|
0.0624 |
0.0624 |
435 |
1 |
0x300 |
0 |
syscall_start |
sysnum: |
4 |
|
|
|
|
|
0.1094 |
0.047 |
435 |
1 |
0x300 |
0 |
syscall_end |
rval1: |
6 |
rval2: |
6 |
errno: |
0 |
|
0.1212 |
0.0118 |
435 |
1 |
0x300 |
0 |
syscall_start |
sysnum: |
3 |
|
|
|
|
|
0.1598 |
0.0386 |
435 |
1 |
0x300 |
0 |
thread_block |
reason: |
0x300021d2a02 |
stack: |
<tnf_symbols> |
|
|
|
0.1776 |
0.0178 |
435 |
1 |
0x300 |
0 |
thread_state |
state: |
7 |
|
|
|
|
|
0.1868 |
0.0092 |
435 |
1 |
0x300 |
0 |
thread_state |
tid: |
0x2a10001fd20 |
state: |
1 |
|
|
|
4276.9288 |
4276.742 |
0 |
0 |
0x2a1 |
0 |
thread_block |
reason: |
0x300007d3c58 |
stack: |
<tnf_symbols> |
|
|
|
4276.9364 |
0.0076 |
0 |
0 |
0x2a1 |
0 |
thread_state |
state: |
7 |
|
|
|
|
|
4276.9372 |
0.0008 |
0 |
0 |
0x2a1 |
0 |
thread_state |
tid: |
0x30001885c40 |
state: |
1 |
|
|
|
5733.5158 |
1456.5786 |
0 |
0 |
0x2a1 |
0 |
thread_block |
reason: |
0x300007d3c58 |
stack: |
<tnf_symbols> |
|
|
|
5733.5242 |
0.0084 |
0 |
0 |
0x2a1 |
0 |
thread_state |
state: |
7 |
|
|
|
|
|
5733.525 |
0.0008 |
0 |
0 |
0x2a1 |
0 |
thread_state |
tid: |
0x30001aaf440 |
state: |
1 |
|
|
|
7900.4296 |
2166.9046 |
0 |
0 |
0x2a1 |
0 |
thread_block |
reason: |
0x300007d3c58 |
stack: |
<tnf_symbols> |
|
|
|
7900.4354 |
0.0058 |
0 |
0 |
0x2a1 |
0 |
thread_state |
state: |
7 |
|
|
|
|
|
7900.4362 |
0.0008 |
0 |
0 |
0x2a1 |
0 |
thread_state |
tid: |
0x30001e1e440 |
state: |
1 |
|
|
|
8684.9232 |
784.487 |
0 |
0 |
0x2a1 |
0 |
thread_block |
reason: |
0x300007d3c58 |
stack: |
<tnf_symbols> |
|
|
|
8684.9304 |
0.0072 |
0 |
0 |
0x2a1 |
0 |
thread_state |
state: |
7 |
|
|
|
|
|
8684.9314 |
0.001 |
0 |
0 |
0x2a1 |
0 |
thread_state |
tid: |
0x30001e5ba60 |
state: |
1 |
|
|
|
12740.737 |
4055.8056 |
374 |
1 |
0x300 |
0 |
syscall_end |
rval1: |
0 |
rval2: |
24 |
errno: |
0 |
|
12740.7594 |
0.0224 |
374 |
1 |
0x300 |
0 |
syscall_start |
sysnum: |
43 |
|
|
|
|
|
12740.7638 |
0.0044 |
374 |
1 |
0x300 |
0 |
syscall_end |
rval1: |
614499 |
rval2: |
3.29857E+12 |
errno: |
0 |
|
12740.7806 |
0.0168 |
374 |
1 |
0x300 |
0 |
syscall_start |
sysnum: |
87 |
|
|
|
|
|
12740.792 |
0.0114 |
374 |
1 |
0x300 |
0 |
thread_block |
reason: |
0x30001c74e02 |
stack: |
<tnf_symbols> |
|
|
|
12740.7986 |
0.0066 |
374 |
1 |
0x300 |
0 |
thread_state |
state: |
7 |
|
|
|
|
|
12740.7994 |
0.0008 |
374 |
1 |
0x300 |
0 |
thread_state |
tid: |
0x2a10001fd20 |
state: |
1 |
|
|
|
13400.6996 |
659.9002 |
0 |
0 |
0x2a1 |
0 |
thread_create |
tid: |
0x2a100831d20 |
pid: |
0 |
start_pc: |
0x7815434c |
13400.7054 |
0.0058 |
0 |
0 |
0x2a1 |
0 |
thread_queue |
tid: |
0x2a100831d20 |
cpuid: |
0 |
priority: |
60 |
queue_length: |
0 |
13400.7068 |
0.0014 |
0 |
0 |
0x2a1 |
0 |
thread_state |
tid: |
0x2a100831d20 |
state: |
8 |
|
|
|
13400.7124 |
0.0056 |
0 |
0 |
0x2a1 |
0 |
thread_block |
reason: |
0x2a10058beb2 |
stack: |
<tnf_symbols> |
|
|
|
13400.7182 |
0.0058 |
0 |
0 |
0x2a1 |
0 |
thread_state |
state: |
7 |
|
|
|
|
|
13400.7192 |
0.001 |
0 |
0 |
0x2a1 |
0 |
thread_state |
tid: |
0x2a100831d20 |
state: |
1 |
|
|
|
15363.6284 |
1962.9092 |
219 |
1 |
0x300 |
0 |
syscall_end |
rval1: |
0 |
rval2: |
4290705264 |
errno: |
0 |
|
15363.6328 |
0.0044 |
219 |
1 |
0x300 |
0 |
syscall_start |
sysnum: |
95 |
|
|
|
|
|
15363.634 |
0.0012 |
219 |
1 |
0x300 |
0 |
syscall_end |
rval1: |
0 |
rval2: |
0 |
errno: |
0 |
|
15363.6366 |
0.0026 |
219 |
1 |
0x300 |
0 |
syscall_start |
sysnum: |
95 |
|
|
|
|
|
15363.6384 |
0.0018 |
219 |
1 |
0x300 |
0 |
syscall_end |
rval1: |
0 |
rval2: |
4290705264 |
errno: |
0 |
|
15363.6508 |
0.0124 |
219 |
1 |
0x300 |
0 |
syscall_start |
sysnum: |
87 |
|
|
|
|
|
15363.86 |
0.2092 |
219 |
1 |
0x300 |
0 |
thread_block |
reason: |
0x300015643da |
stack: |
<tnf_symbols> |
|
|
|
15363.8646 |
0.0046 |
219 |
1 |
0x300 |
0 |
thread_state |
state: |
7 |
|
|
|
|
|
15363.8652 |
0.0006 |
219 |
1 |
0x300 |
0 |
thread_state |
tid: |
0x2a10001fd20 |
state: |
1 |
|
|
|
22305.8478 |
6941.9826 |
276 |
1 |
0x300 |
0 |
thread_state |
state: |
7 |
|
|
|
|
|
22305.849 |
0.0012 |
276 |
1 |
0x300 |
0 |
thread_state |
tid: |
0x3000169f960 |
state: |
0 |
|
|
|
23520.642 |
1214.793 |
0 |
0 |
0x2a1 |
0 |
thread_queue |
tid: |
0x2a100071d20 |
cpuid: |
0 |
priority: |
99 |
queue_length: |
0 |
23520.644 |
0.002 |
0 |
0 |
0x2a1 |
0 |
thread_state |
tid: |
0x2a100071d20 |
state: |
8 |
|
|
|
24290.6388 |
769.9948 |
0 |
0 |
0x2a1 |
0 |
thread_queue |
tid: |
0x2a100077d20 |
cpuid: |
0 |
priority: |
99 |
queue_length: |
0 |
24290.6406 |
0.0018 |
0 |
0 |
0x2a1 |
0 |
thread_state |
tid: |
0x2a100077d20 |
state: |
8 |
|
|
|
25280.6458 |
990.0052 |
0 |
0 |
0x2a1 |
0 |
thread_queue |
tid: |
0x2a100071d20 |
cpuid: |
0 |
priority: |
99 |
queue_length: |
1 |
25280.6474 |
0.0016 |
0 |
0 |
0x2a1 |
0 |
thread_state |
tid: |
0x2a100071d20 |
state: |
8 |
|
|
|
25430.6406 |
149.9932 |
0 |
0 |
0x2a1 |
0 |
thread_queue |
tid: |
0x2a100077d20 |
cpuid: |
0 |
priority: |
99 |
queue_length: |
1 |
25430.6416 |
0.001 |
0 |
0 |
0x2a1 |
0 |
thread_state |
tid: |
0x2a100077d20 |
state: |
8 |
|
|
|
29402.7118 |
3972.0702 |
0 |
0 |
0x2a1 |
0 |
thread_block |
reason: |
0x300007d3e38 |
stack: |
<tnf_symbols> |
|
|
|
|
図9.4 tnfdumpの出力(抜粋)
表9に項目の内容を示します。
表9.tnfdumpの出力項目
項目 |
内容 |
Elapsed(ms) |
ミリ秒(ms)単位の最初のプローブからの経過時間。 |
Delta(ms) |
ミリ秒(ms)単位の処理時間。 |
PID |
プロセスID |
LWPID |
LWPのID |
TID |
トレースID |
CPU |
実行CPU |
Probe Name |
プローブ名 |
Data |
各プローブに対応したデータ。 |
Description |
詳細な情報【備考】 |
【備考】プローブによって内容が異なります。prex(1)カーネルトレースをご覧下さい。
ICPUイベントの内訳は?
CPUに発生している各種イベントの見方を解説します(ここまで詳細に調査することは稀ですが…)。
# cpustat -h <CR>
Usage:
cpustat [-c events] [-nhD] [interval [count]]
-c events specify processor events to be monitored
-n suppress titles
-t include %tick register
-D enable debug mode
-h print extended usage information
Use cputrack(1) to monitor per-process statistics.
CPU performance counter interface: UltraSPARC III+
events pic0=<event0>,pic1=<event1>[,sys][,nouser]
event0: Cycle_cnt Instr_cnt Dispatch0_IC_miss IC_ref DC_rd DC_wr
EC_ref EC_snoop_inv Dispatch0_br_target Dispatch0_2nd_br
Rstall_storeQ Rstall_IU_use EC_write_hit_RTO EC_rd_miss
PC_port0_rd SI_snoop SI_ciq_flow SI_owned SW_count_0
IU_Stat_Br_miss_taken IU_Stat_Br_count_taken
Dispatch_rs_mispred FA_pipe_completion MC_reads_0
MC_reads_1 MC_reads_2 MC_reads_3 MC_stalls_0 MC_stalls_2
EC_wb_remote EC_miss_local EC_miss_mtag_remote
event1: Cycle_cnt Instr_cnt Dispatch0_mispred EC_wb EC_snoop_cb
IC_miss_cancelled Re_FPU_bypass Re_DC_miss Re_EC_miss
IC_miss DC_rd_miss DC_wr_miss Rstall_FP_use EC_misses
EC_ic_miss Re_PC_miss ITLB_miss DTLB_miss WC_miss
WC_snoop_cb WC_scrubbed WC_wb_wo_read PC_soft_hit
PC_snoop_inv PC_hard_hit PC_port1_rd SW_count_1
IU_Stat_Br_miss_untaken IU_Stat_Br_count_untaken
PC_MS_misses MC_writes_0 MC_writes_1 MC_writes_2
MC_writes_3 MC_stalls_1 MC_stalls_3 Re_RAW_miss
FM_pipe_completion Re_DC_missovhd EC_miss_mtag_remote
EC_miss_remote
See the "SPARC V9 JPS1 Implementation Supplement: Sun
UltraSPARC-III+"
# |
図10.1 cpustatコマンドの出力
図10.1の11行目のpicは、Performance Instrumentation Counterの略です。このeventsをcputrackコマンドの引数に指定します。
# cputrack -c pic0=Cycle_cnt,pic1=Instr_cnt sweep <CR>
time lwp event pic0 pic1
1.024 1 tick 549287730 361513532
2.014 1 tick 471780029 310465907
3.014 1 tick 427952560 281452157
4.024 1 tick 405079082 267091704
5.004 1 tick 358544103 236641843
6.014 1 tick 344758443 228059522
7.025 1 tick 337806506 223112694
8.004 1 tick 306581324 202556383
# |
図10.2 cputrackコマンドの出力例
cpustatで表示されるイベント詳細は、UltraSPARC III Cu User's Manual( http://www.sun.com/processors/manuals/USIIIv2.pdf…CPUアーキテクチャによってマニュアル名称、およびURLアドレスが異なります)をご覧ください。また、参考文献2にすっきりとまとまった表がありますので、ご覧ください。
Copyright (C) 2004 by The Art of Computer Technologies, Corp. All
rights reserved.