doProfile 8.55 KB
#!/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. 
#

# Generate a fancy profile graph 

if (defined($ENV{'SIMTOOLS'}) ) { 
     unshift(@INC,"$ENV{'SIMTOOLS'}/apps/scripts");
}

require "tree.prl";

$showKey = 1;
$showRemote = 1;
$showSyncStall = 0;
$showRpc = 0;

$inputFile = "cpu.log";
$grouping = 1;
$startNode = "ROOT";
$title = "profile";
$xmax = "FLOATING";
 
$i=0;
while ($i<=$#ARGV) {
    if ($ARGV[$i] eq "-g") {
        $i++;
        $grouping = $ARGV[$i];
        
    } elsif ($ARGV[$i] eq "-f") {
        $i++;
        $inputFile = $ARGV[$i];
        
    } elsif ($ARGV[$i] eq "-x") {
        $i++;
        $xmax = $ARGV[$i];

    } elsif ($ARGV[$i] eq "-nokey") {
        $showKey = 0;
        
    } elsif ($ARGV[$i] eq "-noremote") {
        $showRemote = 0;
        
    } elsif ($ARGV[$i] eq "-syncstall") {
        $showSyncStall = 1;
        
    } elsif ($ARGV[$i] eq "-s") {
        $i++;
        $startNode = $ARGV[$i];

    } elsif ($ARGV[$i] eq "-rpc") {
        $showRpc = 1;
        
    } elsif ($ARGV[$i] eq "-t") {
        $i++;
        $title = $ARGV[$i];
        
    } else {
        print "usage: doProfile [-nokey] [-noremote] [-syncstall] [-rpc]\n";
        print "                 [-g grouping] [-f file] [-s node] [-t title]\n";
        print "                 [-x xmax (in seconds)]\n";
        exit;
    }
    $i++;
}

print STDERR "Generating profile graph $title.ps from $inputFile\n";

open(INFILE, $inputFile) || die "ERROR: could not open $inputFile";

if ($showKey) {
    open(STDOUT, "| time-profile.prl $title $xmax | splot | fix-bounding-box.prl > $title.ps");
} else {
    open(STDOUT, "| time-profile.prl $title $xmax | splot > $title.ps");
}


#
# setup breakdown
#

%states = (PhaseName($startNode) => ["user"],
           "kernel" => ["kernel"],
           "idle" => ["idle"],
           "sync" => ["sync"],
           "rpcwait" => ["rpcwait"],
           "pal" =>["pal"]
           );

@modes = ({'name' => "kernel",
               'treetag' => "kernel",
               'color' => "green",
               'stall' => "yellow"},
          {'name' => "kernel sync",
               'treetag' => "sync",
               'color' => "red"},
         {'name' => "PALcode",
              'treetag' =>"pal",
              'color' =>"black"},
          {'name' => "user",
               'treetag' => "user",
               'color' => "aquamarine",
               'stall' => "blue"},
          {'name' => "user spin",
               'treetag' => "spin",
               'color' => "black"},
          {'name' => "idle",
               'treetag' => "idle",
               'color' => "white"} );

if ($showSyncStall) {
    $modes[1]{'stall'} = "purple";
    $modes[1]{'remstall'} = "pink";
}

if ($showRemote) {
    $modes[0]{'remstall'} = "orange";
    $modes[2]{'remstall'} = "DarkSlateGray";
}

if ($showRpc) {
    splice(@modes,2,0,{'name' => "rpc wait",
                       'treetag' => "rpcwait",
                       'color' => "pink"});
}

#
# main loop
#

$iter = 0;
$prevtime = 0;
$group = 0;
$remotePresent = 0;

while ($tree = ParseNextTree(\*INFILE, "modes")) {

    $group++;
    if ($group < $grouping) {
        next;
    }
    $group = 0;

    if ($iter && $tree->{"ROOT"}{"time"} == $abstime[$iter-1]) {
        ## the last tree is printed out twice in embra, avoid this
        next;
    }
    
    $abstime[$iter] = $tree->{'ROOT'}{'time'};
    $time[$iter] = $abstime[$iter] - $prevtime;
    $prevtime = $abstime[$iter];

    $comp = SumTree($tree, $startNode, \%states, 1);

    foreach $tag (keys %$comp) {
        if (defined($prev{$tag}{"cycles"})) {
            $data[$iter]{$tag}{"cycles"} = $comp->{$tag}{'_cycles'} -
                $prev{$tag}{"cycles"};
            $data[$iter]{$tag}{"dstall"} = $comp->{$tag}{'dStall'} -
                $prev{$tag}{"dstall"};
            $data[$iter]{$tag}{"istall"} = $comp->{$tag}{'iStall'} -
                $prev{$tag}{"istall"};
            $data[$iter]{$tag}{"dL2RemoteStall"} = $comp->{$tag}{"dL2RemoteStall"} -
                $prev{$tag}{"dL2RemoteStall"};
            $data[$iter]{$tag}{"iL2RemoteStall"} = $comp->{$tag}{"iL2RemoteStall"} -
                $prev{$tag}{"iL2RemoteStall"};
        } else {
            $data[$iter]{$tag}{"cycles"} = $comp->{$tag}{'_cycles'};
            $data[$iter]{$tag}{"dstall"} = $comp->{$tag}{'dStall'};
            $data[$iter]{$tag}{"istall"} = $comp->{$tag}{'iStall'};
            $data[$iter]{$tag}{"dL2RemoteStall"} = $comp->{$tag}{"dL2RemoteStall"};
            $data[$iter]{$tag}{"iL2RemoteStall"} = $comp->{$tag}{"iL2RemoteStall"};
        }
        
        if ($comp->{$tag}{"dL2RemoteStall"} || $comp->{$tag}{"iL2RemoteStall"}) {
            $remotePresent = 1;
        }
        
        $prev{$tag}{"cycles"}  = $comp->{$tag}{'_cycles'};
        $prev{$tag}{"dstall"}  = $comp->{$tag}{'dStall'};
        $prev{$tag}{"istall"}  = $comp->{$tag}{'iStall'};
        $prev{$tag}{"dL2RemoteStall"} = $comp->{$tag}{"dL2RemoteStall"};
        $prev{$tag}{"iL2RemoteStall"} = $comp->{$tag}{"iL2RemoteStall"};
    }

    $iter++;
}

close(INFILE);


###
### Print out data
###

if (defined($config{"Clock"})) {
    print "CLOCK $config{Clock}\n";
}

if ($showKey) {
    print "USE_KEY\n";
}


print "BREAKDOWN";

foreach $m (0..$#modes) {
    $tag = $modes[$m]{'treetag'};
    if (defined($data[$#data]{$tag})) {
        if (!defined($modes[$m]{'stall'})) {
            print "\t$modes[$m]{'name'}";
        } elsif ($remotePresent && defined($modes[$m]{'remstall'})) {
            print "\t$modes[$m]{'name'} instr";
            print "\t$modes[$m]{'name'} local stall\t$modes[$m]{'name'} remote stall";
        } else {
            print "\t$modes[$m]{'name'} instr\t$modes[$m]{'name'} stall";
        }
    }
}

print "\n";

print "COLOR";

foreach $m (0..$#modes) {
    $tag = $modes[$m]{'treetag'};
    if (defined($data[$#data]{$tag})) {
        if (!defined($modes[$m]{'stall'})) {
            print "\tcolor $modes[$m]{'color'}";
        } elsif ($remotePresent && defined($modes[$m]{'remstall'})) {
            print "\tcolor $modes[$m]{'color'}";
            print "\tcolor $modes[$m]{'stall'}\tcolor $modes[$m]{'remstall'}";
        } else {
            print "\tcolor $modes[$m]{'color'}\tcolor $modes[$m]{'stall'}";
        }
    }
}

print "\n";


foreach $i (0..$#data) {
    printf "%6.3f ", $abstime[$i] / 1000000.0;

    $total = 0;

    foreach $m (0..$#modes) {
        $tag = $modes[$m]{'treetag'};
        if (defined($data[$#data]{$tag})) {
            if (!defined($modes[$m]{'stall'})) {
                if (defined($data[$i]{$tag})) {
                    $total += (100.0 * $data[$i]{$tag}{"cycles"}) /
                        ($config{"NumCPUs"} * $time[$i]);
                }
                printf "\t%4.2f", $total;

            } elsif ($remotePresent && defined($modes[$m]{'remstall'})) {
                if (defined($data[$i]{$tag})) {
                    $remstall = $data[$i]{$tag}{"dL2RemoteStall"} +
                        $data[$i]{$tag}{"iL2RemoteStall"};
                    $stall = $data[$i]{$tag}{"dstall"} + $data[$i]{$tag}{"istall"} -
                        $remstall;

                    $c = $data[$i]{$tag}{"cycles"} - $stall - $remstall;

                    $total += (100.0 * $c) /
                        ($config{"NumCPUs"} * $time[$i]);
                    printf "\t%4.2f", $total;
                    
                    $total += (100.0 * $stall) /
                        ($config{"NumCPUs"} * $time[$i]);
                    printf "\t%4.2f", $total;
                    
                    $total += (100.0 * $remstall) /
                        ($config{"NumCPUs"} * $time[$i]);
                    printf "\t%4.2f", $total;

                } else {
                    printf "\t%4.2f\t%4.2f\t%4.2f", $total, $total, $total;
                }
                
            } else {
                if (defined($data[$i]{$tag})) {
                    $stall = $data[$i]{$tag}{"dstall"} + $data[$i]{$tag}{"istall"};
                    $c = $data[$i]{$tag}{"cycles"} - $stall;

                    $total += (100.0 * $c) /
                        ($config{"NumCPUs"} * $time[$i]);
                    printf "\t%4.2f", $total;
                    
                    $total += (100.0 * $stall) /
                        ($config{"NumCPUs"} * $time[$i]);
                    printf "\t%4.2f", $total;

                } else {
                    printf "\t%4.2f\t%4.2f", $total, $total;
                }
            }
        }
    }

    print "\n";
}