#!/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 = <INF>) {
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";
syntax highlighted by Code2HTML, v. 0.9.1