📄 kstats
字号:
#!/usr/local/bin/perl5 -w## Copyright (C) 1996-1998 by the Board of Trustees# of Leland Stanford Junior University.# # This file is part of the SimOS distribution. # See LICENSE file for terms of the license. #%config = ();if (defined($ENV{'SIMOS_DIR'})) { unshift(@INC,"$ENV{'SIMOS_DIR'}/src/apps/scripts");}require "tree.prl";$inputFile = "cpu.log";$numServices = -1;$checkMode = 0;$hive = 0;$startnode = "ROOT";$i=0;while ($i<=$#ARGV) { if ($ARGV[$i] eq "-f") { $i++; $inputFile = $ARGV[$i]; } elsif ($ARGV[$i] eq "-n") { $i++; $numServices = $ARGV[$i]; } elsif ($ARGV[$i] eq "-m") { $checkMode = 1; } elsif ($ARGV[$i] eq "-H") { $hive = 1; } elsif ($ARGV[$i] eq "-s") { $i++; $startnode = $ARGV[$i]; } elsif ($ARGV[$i] eq "-S") { $i++; $showService{$ARGV[$i]} = 1; } elsif ($ARGV[$i] eq "-t") { $i++; $showTable{$ARGV[$i]} = 1; } else { print "usage: kstats [-f file] [-H <hive>] [-s startNode]\n"; print " [-m <check modes tree consistency>]\n"; print " [-n num_services] [-S service] [-t table_num]\n"; exit; } $i++;}###### parse kstats tree ###$tree = ParseTree($inputFile, "kstats");if (!$tree) { print "FATAL ERROR: no tree found, you must not have source'd kernel_stats.tcl\n"; exit (-1);}$total = TotalTree($tree, $startnode);$clock = 1.0 * $config{"Clock"};SetupConstants();###### get the basic breakdown#### non-kernel modes%bstates = ( PhaseName($startnode) => ["user"], "idle" => ["idle"], "sync" => ["sync"], "fastRPC" => ["fastRPC"], );# kernel entry pointsforeach $i (1000..1180) { $bstates{"syscall($i)"} = ["kernel"];}foreach $i (0..15) { $bstates{"exc($i)"} = ["kernel"];}foreach $i (0 .. $#kernel_states) { $bstates{$kernel_states[$i]} = ["kernel"];}# doit$compBasic = SumTree($tree, $startnode, \%bstates, 1);###### Get some overall constants that will survive to be used later### after the bstates and compBasic arrays are discarded###$kstall = $compBasic->{'kernel'}{'dStall'} + $compBasic->{'kernel'}{'iStall'};$ustall = $compBasic->{'user'}{'dStall'} + $compBasic->{'user'}{'iStall'};if (!$hive) { $ktotal = $compBasic->{'sync'}{'comptotal'} + $compBasic->{'kernel'}{'comptotal'}; $kexec = $compBasic->{'kernel'}{'comptotal'} - $kstall;} else { $ktotal = $compBasic->{'sync'}{'comptotal'} + $compBasic->{'fastRPC'}{'comptotal'} + $compBasic->{'kernel'}{'comptotal'}; $kexec = $compBasic->{'kernel'}{'comptotal'} - $kstall;}###### check overall timings against mode tree if requested###if ($checkMode) { $modes = ParseTree($inputFile, "modes"); $mismatch = 0; $compModes = SumTree($modes, $startnode, \%bstates, 1); foreach $s (sort(keys %$compModes)) { if (!defined($compBasic->{$s})) { print "WARNING: $s not defined in kstats\n"; $mismatch = 1; } elsif ($compModes->{$s}{"comptotal"} != $compBasic->{$s}{"comptotal"}) { print "WARNING: $s in modes != kstats\n"; $mismatch = 1; } } if ($mismatch) { exit(-1); }}###### table 0 : overall timings ###sub PrintFraction { ($indent, $name, $val) = @_; printf "%-" . $indent . "s %5.2f%%\n", $name, 100.0 * $val / $total->{'comptotal'};}if (!defined(%showTable) || defined($showTable{"0"})) { print "\n"; print "+--------------------------------------+\n"; print "| 0: basic breakdown of execution time |\n"; print "+--------------------------------------+\n\n"; PrintFraction(18, "user", $compBasic->{'user'}{'comptotal'}); PrintFraction(10, " exec", $compBasic->{'user'}{'comptotal'}-$ustall); PrintFraction(10, " stall", $ustall); PrintFraction(12, " data", $compBasic->{'user'}{'dStall'}); PrintFraction(12, " inst", $compBasic->{'user'}{'iStall'}); PrintFraction(18, "kernel", $ktotal); PrintFraction(10, " exec", $kexec); PrintFraction(10, " stall", $kstall); PrintFraction(12, " data", $compBasic->{'kernel'}{'dStall'}); PrintFraction(12, " inst", $compBasic->{'kernel'}{'iStall'}); PrintFraction(10, " sync", $compBasic->{'sync'}{'comptotal'}); if ($hive) { PrintFraction(10, " RPC", $compBasic->{'fastRPC'}{'comptotal'}); } PrintFraction(18, "idle", $compBasic->{'idle'}{'comptotal'}); print "\n";}undef(%bstates);undef($compBasic);###### sum up kernel computation time by service performed### # for each service, break down time into computation, stall,# and one or several subcategoriesif (!$hive) { @subcategories = ("sync"); @subcatnames = ("sync");} else { @subcategories = ("sync", "fastRPC"); @subcatnames = ("sync", "fRPC");}%states = ();$states{PhaseName($startnode)} = ["user", "ROOT"];# named kernel entry pointsforeach $i (0 .. $#kernel_states) { $states{$kernel_states[$i]} = [$kernel_states[$i], "ROOT"];}# syscallsforeach $i (1000..1180) { $states{"syscall($i)"} = ["$syscallName[$i]", "ROOT"];}# exceptionsforeach $i (0..31) { if (defined($excName[$i])) { $states{"exc($i)"} = ["$excName[$i]", "ROOT"]; } else { $states{"exc($i)"} = ["exc($i)", "ROOT"]; }}# RPC servicesif ($hive) { foreach $i (0 .. 31) { $sname = "fmethod(" . sprintf("0x%lx", $i) . ")"; if (defined($fmethodName[$i])) { $states{$sname} = [$fmethodName[$i], "ROOT"]; } else { $states{$sname} = [$sname, "ROOT"]; } } foreach $i (0 .. 63) { $sname = "qmethod(" . sprintf("0x%lx", $i) . ")"; if (defined($qmethodName[$i])) { $states{$sname} = [$qmethodName[$i], "ROOT"]; } else { $states{$sname} = [$sname, "ROOT"]; } }}# subcategoriesforeach $subcat (@subcategories) { $states{$subcat} = [0, $subcat];}# doit$comp = SumTree($tree, $startnode, \%states, 2);###### find all buckets which accumulated any time and sort in decreasing### order###$i = 0;foreach $state (keys %$comp) { @names = split(/:/, $state); if (($names[0] ne "user") && ($names[0] ne "idleproc") && ($names[0] ne "runq") && ($names[1] eq "ROOT")) { $services[$i++] = $names[0]; }}@services = sort bycomp @services;###### TABLE 1###### table 1 is kernel services sorted by % of kernel time###sub PrintFieldname { local ($fname) = @_; printf "%7s", $fname;}sub PrintFraction2 { local ($amt, $tc) = @_; printf " %5.0f", 100.0 * $amt / $tc;}if (!defined(%showTable) || defined($showTable{"1"})) { print "\n"; print "+-------------------------------------+\n"; print "| 1: computation breakdown by service |\n"; print "+-------------------------------------+\n\n"; printf "%-20s %6s %8s %12s ", "service", "kern %", "num", "avg cycles"; PrintFieldname("%exec"); PrintFieldname("%stall"); foreach $i (0 .. $#subcategories) { PrintFieldname("%" . $subcatnames[$i]); } print "\n"; print "-" x (20+7+9+13+2); PrintFieldname("-" x 7); PrintFieldname("-" x 7); foreach $subcat (@subcategories) { PrintFieldname("-" x 7); } print "\n"; $servicenum = 0; foreach $s (@services) { $servicenum++; if (!printService($s, $servicenum)) { next; } $stall = $comp->{"$s:ROOT"}{"dStall"} + $comp->{"$s:ROOT"}{"iStall"}; $cexec = $comp->{"$s:ROOT"}{"comptotal"} - $stall; $totcomp = $comp->{"$s:ROOT"}{"comptotal"}; foreach $i (0 .. $#subcategories) { $sstring = "$s:" . $subcategories[$i]; if (defined($comp->{$sstring})) { $subcatval[$i] = $comp->{$sstring}{"comptotal"}; } else { $subcatval[$i] = 0; } $totcomp += $subcatval[$i]; } $n = $comp->{"$s:ROOT"}{'n'}; if ($n == 0) { printf "%-16s no entries\n", $s; next; } printf "%-20s %5.2f%% %8d %12.2f ", $s, 100.0 * $totcomp / $ktotal, $n, $totcomp / $n; PrintFraction2($cexec, $totcomp); PrintFraction2($stall, $totcomp); foreach $i (0 .. $#subcategories) { PrintFraction2($subcatval[$i], $totcomp); } print "\n"; }}###### TABLE 2###### table 2 is latency of kernel services sorted by average latency#### carry forward the same breakdown states table, but delete the# subcategories that record stall times and add those for blocking# timesforeach $subcat (@subcategories) { delete($states{$subcat});}if (!$hive) { @subcategories = ("semawait", "runq", "diskIO"); @subcatnames = ("sema", "runq", "disk");} else { @subcategories = ("semawait", "runq", "diskIO", "fastRPCblock", "queuedRPC"); @subcatnames = ("sema", "runq", "disk", "fRPC", "qRPC");}foreach $subcat (@subcategories) { $states{$subcat} = [0, $subcat];}# doit$comp = SumTree($tree, $startnode, \%states, 2); if (!defined(%showTable) || defined($showTable{"2"})) { print "\n"; print "+---------------------------------+\n"; print "| 2: latency breakdown by service |\n"; print "+---------------------------------+\n\n"; printf "%-20s %9s %9s %9s ", "service", "avg (us)", "min (us)", "max (us)"; PrintFieldname("%comp"); PrintFieldname("%exc"); foreach $i (0 .. $#subcategories) { PrintFieldname("%" . $subcatnames[$i]); } print "\n"; print "-" x (20+10+10+10+3); PrintFieldname("-" x 7); PrintFieldname("-" x 7); foreach $subcat (@subcategories) { PrintFieldname("-" x 7); } print "\n"; $servicenum = 0; foreach $s (@services) { $servicenum++; if (!printService($s, $servicenum)) { next; } $totsubcats = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -