#!/usr/bin/perl -w use strict; use Statistics::Distributions; my $last_thread = -1; my $last_end; my @ctx; my %hist; my $BUCKET_SIZE = $ARGV[1]; die if (!defined ($BUCKET_SIZE)); print "\n\nbucket size is $BUCKET_SIZE\n"; my $infn = $ARGV[0]; die if (!defined ($infn)); if (!(open INF, "cat $infn |")) { if (!(open INF, "bzcat -cd $infn.bz2 |")) { die; } } while (my $line = ) { if ($line =~ /^tracerec: ([0-9]+) ([0-9\.]+) ([0-9\.]+) /) { my $thread = $1; my $start = $2; my $end = $3; if ($last_thread != -1 && $thread != $last_thread) { my $gap = 1000 * ($start - $last_end); push @ctx, $gap; my $bucket = int ($gap/$BUCKET_SIZE); $hist{$bucket}++; } $last_thread = $thread; $last_end = $end; } } close INF; my $len = scalar (@ctx); sub bynum { $a <=> $b; } my @ctx2 = sort bynum @ctx; open OUTF, ">".$infn."_hist.dat" or die; foreach my $val (sort bynum keys %hist) { print OUTF $val*$BUCKET_SIZE." $hist{$val}\n"; } close OUTF; sub percentile ($$) { my $pctile = (shift) / 100.0; my $x = shift; my @data = @$x; my $len = scalar (@data); return $data[int($len*$pctile)]; } sub median ($) { return percentile (shift, 50); } sub mean ($) { my $x = shift; my @data = @$x; my $total = 0.0; my $len = scalar (@data); foreach (@data) { $total += $_; } return $total / $len; } sub trim ($$) { my $x = shift; my $frac = shift; my @data = @$x; my @data2 = @data; my $len = scalar (@data2); my $low = int($len*$frac); my $high = int($len-($len*$frac)); my @data3 = @data2[$low..$high]; return @data3; } sub stdev ($) { my $x = shift; my @data = @$x; my $total; my $len = scalar (@data); my $avg = mean (\@data); $total = 0.0; foreach (@data) { my $inc = ($_ - $avg) * ($_ - $avg); #print "$_ $avg $inc\n"; $total += $inc; } $total /= $len-1; return sqrt ($total); } sub confidence ($$) { my $x = shift; my $conf = shift; my @data = @$x; my $avg = mean (\@data); my $a = 1.0-$conf; my $aa = 1.0-($a/2); my $z = -Statistics::Distributions::udistr ($aa); my $std = stdev (\@data); print " stdev = $std\n"; print " z ($aa) = $z\n"; my $low = $avg - ($z*$std/sqrt($len)); my $high = $avg + ($z*$std/sqrt($len)); return ($low, $high); } print "$infn :\n"; print " 25th %ile ".percentile(25,\@ctx2)."\n"; print " 50th %ile ".percentile(50,\@ctx2)."\n"; print " 75th %ile ".percentile(75,\@ctx2)."\n"; print " mean = ".mean(\@ctx2)."\n"; my $cnt = scalar (@ctx2); print " $cnt total context switches\n"; print "\n"; print "after trimming:\n"; my @ctx3 = trim (\@ctx2, 0.10); $cnt = scalar (@ctx3); print " $cnt total context switches\n"; print " 25th %ile ".percentile(25,\@ctx3)."\n"; print " 50th %ile ".percentile(50,\@ctx3)."\n"; print " 75th %ile ".percentile(75,\@ctx3)."\n"; print " mean = ".mean(\@ctx3)."\n"; (my $low, my $high) = confidence (\@ctx3, 0.95); print " 95% confidence that mean is in the range $low .. $high\n";