emSum.prl 10.4 KB
#!/usr/local/bin/perl5
#
# 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. 
#

unshift(@INC, "/morse/m4/witchel/bin/");
unshift(@INC, "/morse/m4/witchel/bin/Stats");
unshift(@INC, "/morse/m4/witchel/bin/Stats/Basic.pm");
require "Basic.pm";
#use Stats::Basic;

@Modes = ('K', 'U', 'I', 'S', 'T');

require "getopts.pl";
&Getopts('cl');
# -c for consistency output check
# -l for long output (stat breakdown)

$inputFile = shift;
if( !defined $inputFile ) {
    $inputFile = "cpu.log";
}


$mipsInfo = Stats::Basic->new;
$transInfo = Stats::Basic->new;
$clkInfo = Stats::Basic->new;
# Page Mode
$mmuMissInfo = Stats::Basic->new;

open(LOG, $inputFile) || die "Failed to open $inputFile $.\n";
while(<LOG>){
    if(/^CONFIG EmPCSample\s+(\d+)/) {
        $pcSampleRate = $1;
    }
    if(/^CONFIG EmStatInterval\s+(\d+)/) {
        $emStatInterval = $1;
    }
    if(/^CONFIG NumCPUs\s+(\d+)/) {
        $numCPUs = $1;
    }
    if(/^CONFIG CpuClock\s+(\d+)/) {
        $cpuClock = $1;
    }
    if(/^CONFIG MemCycleTime\s+(\d+)/) {
        if( !defined $cpuClock ) {
            die "Need CpuClock before MemCycleTime\n";
        }
        $memCycleTime = $1 * $cpuClock / 1000;
    }
    if(/^CONFIG SCacheLineSize\s+(\d+)/) {
        $sCacheLineSize = $1;
    }
    if(/Usec (\d+)/) {
        if( !defined $startUsec ) { $startUsec = $1; }
        $cur{'usec'} = $1;
    }
    # Get a notion of simulated time
    if(/^EM_CPU 0 Cycle (\d+)/) {
        $cur{'cycleCount'} = $1 * $numCPUs;
    }
    # This occurs in cache mode not page mode
    if(/^EM_CS_(\w)/) {
        ($label, $pcSamples{$1}, $dStall{$1}, $iStall{$1}, $iCount{$1}, 
         $iMiss{$1}, $dRefs{$1}, $dMiss{$1}, $upgrades{$1} ) = split;
        $cur{'pcSamples'} += $pcSamples{$1};
    }
    if(/^EM_PCTC/){
        $cur{'pctcLine'} = $_;
    }
    # This occurs in page mode, not cache mode
    if(/^EM_MMU/){
        $pageMode = 1;
        split;
        $cur{'mmuSMissCount'} = $_[3];
        $cur{'mmuXMissCount'} = $_[4];
    }
    if(/^EM_QC/){
        $cur{'emqcLine'} = $_;
    }
    if(/^EM_C0/){
        split;
        $cur{'clkCount'} = $_[4];
        $cur{'exc_int'} = $_[6];
        $cur{'exc_mod'} = $_[8];
        ($ker, $user) = split(/\//, $_[10]);
        $cur{'exc_rmiss'} = $ker + $user;
        ($ker, $user) = split(/\//, $_[12]);
        $cur{'exc_wmiss'} = $ker + $user;
        $cur{'exc_syscall'} = $_[14];
    }
    if(/^EM_T Tran ([0-9\.]+)s/) {
        $cur{'transTime'} = $1;
    }
    if(/^EM_B.*Bdr ([0-9\.]+)r/) {
        $bdAccesses = $1;
    }
    if(/^EmbraRunTime\s*([0-9\.]+) sec/) {
        $realSec = $1;
        $realMin = $1/60;
    }
    # End Frame
    if(/^EM_X/) {
        $mmuMissInfo->AddData( 
                   100*(($cur{'mmuSMissCount'} + $cur{'mmuXMissCount'}) - 
                       ($prev{'mmuSMissCount'} + $prev{'mmuXMissCount'}))/
                              ($cur{'cycleCount'} - $prev{'cycleCount'} ));
        $prev{'mmuSMissCount'} = $cur{'mmuSMissCount'};
        $prev{'mmuXMissCount'} = $cur{'mmuXMissCount'};
        if( $pageMode ) {
            $mipsInfo->AddData( ($cur{'cycleCount'} - $prev{'cycleCount'})/
                               ( $cur{'usec'} - $prev{'usec'} ) );
            $prev{'cycleCount'} = $cur{'cycleCount'};
        } else {
            $mipsInfo->AddData( $pcSampleRate * 
                               ($cur{'pcSamples'} - $prev{'pcSamples'}) /
                               ( $cur{'usec'} - $prev{'usec'} ) );
            $prev{'pcSamples'} = $cur{'pcSamples'};
            $cur{'pcSamples'} = 0;
        }
        $transInfo->AddData( $cur{'transTime'} - $prev{'transTime'} );
        $prev{'transTime'} = $cur{'transTime'};
        $clkInfo->AddData( $cur{'clkCount'} - $prev{'clkCount'} );
        $prev{'clkCount'} = $cur{'clkCount'};
        $prev{'usec'} = $cur{'usec'};
    }
}

if( !$realMin ) {
    $realMin = ($cur{'usec'} - $startUsec)/(1000*1000*60);
}
$simSec = $cur{'cycleCount'}/($numCPUs * $cpuClock * 1000 * 1000);
if( $simSec ) {
    printf("Real  %d sec  %.2f min\nSim      %.2f sec\nSlowdown %.2fx %.2fx/proc\n",
           $realSec, $realMin, $simSec, ($realMin * 60)/$simSec, 
           ($realMin*60)/($simSec*$numCPUs) );
} else {
    print "Real $realSec sec $realMin min\n";
}
@mipsStats = ("Min", "Max", "Median", "Mean", "SD", "Coeff");
if( $opt_l ) {
    print join("\t", @mipsStats), "\n";
}
printf "MIPS AVG %.2f\n", 
    $cur{'cycleCount'}/($cur{'usec'} - $startUsec);
if( $opt_l ) {
    printf("%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.3f\n",
           $mipsInfo->Min,                          
           $mipsInfo->Max,                          
           $mipsInfo->Median,
           $mipsInfo->Mean,
           $mipsInfo->StandardDeviation,
           $mipsInfo->CoefficientOfVariance );
}
printf "TRANSLATION TIME (s) %d sec %.2f%% of total time\n", 
    $cur{'transTime'},
    100*1000*1000*$cur{'transTime'}/($cur{'usec'} - $startUsec);
if( $opt_l ) {
    printf("%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.3f\n",
           $transInfo->Min,                          
           $transInfo->Max,                          
           $transInfo->Median,
           $transInfo->Mean,
           $transInfo->StandardDeviation,
           $transInfo->CoefficientOfVariance );
}
# Time divided by simulated time
printf "CLK RATE (count) AVG slowdown %.2f\n",
    $numCPUs * ($cur{'usec'} - $startUsec)/($cur{'clkCount'} * 10 * 1000);
if( $opt_l ) {
    printf("%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.3f\n",
           $clkInfo->Min,                          
           $clkInfo->Max,                          
           $clkInfo->Median,
           $clkInfo->Mean,
           $clkInfo->StandardDeviation,
           $clkInfo->CoefficientOfVariance );
}
# Time divided by simulated time
if( $pageMode ) {
    printf "MMU Misses (rate) AVG %.2f%% SHARED %.2f%% EXCL %.2f%%\n",
    100*($cur{'mmuSMissCount'} + $cur{'mmuXMissCount'})/$cur{'cycleCount'},
    100*$cur{'mmuSMissCount'}/($cur{'mmuSMissCount'} + $cur{'mmuXMissCount'}),
    100*$cur{'mmuXMissCount'}/($cur{'mmuSMissCount'} + $cur{'mmuXMissCount'});
    if( $opt_l ) {
        printf("%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.3f\n",
               $mmuMissInfo->Min,                          
               $mmuMissInfo->Max,                          
               $mmuMissInfo->Median,
               $mmuMissInfo->Mean,
               $mmuMissInfo->StandardDeviation,
               $mmuMissInfo->CoefficientOfVariance );
    }
} else {
    split(/[ \n\t]+/, $cur{'emqcLine'});
    $totdRefs = 0;
    $totiCount = 0;
    foreach $mode (@Modes) {
        $totdRefs += $dRefs{$mode};
        $totiCount += $iCount{$mode};
    }
    #100*($_[2] + $_[3] + $_[4])/$cur{'cycleCount'},
#    printf("VQC Miss %.2f-%.2f%%I %.2f%%D %.2f%%B INSTR %.2f%% SHARED %.2f%% EXCL %.2f%%\n",
#           100*$_[2]/$totiCount, 100*$_[2]/($totiCount/($sCacheLineSize/4)), 
#           100*($_[3] + $_[4])/$totdRefs,
#           100*$bdAccesses/($_[2] + $_[3] + $_[4]),
#           100*$_[2]/($_[2] + $_[3] + $_[4]),
#           100*$_[3]/($_[2] + $_[3] + $_[4]),
#           100*$_[4]/($_[2] + $_[3] + $_[4]) );
#    printf("PQC Miss %.2f%% INSTR %.2f%% SHARED %.2f%% EXCL %.2f%%\n",
#           100*($_[5] + $_[6] + $_[7])/($_[2] + $_[3] + $_[4]),
#           100*$_[5]/$_[2],
#           100*$_[6]/$_[3],
#           100*$_[7]/$_[4] );
    if( $opt_c ) {
        print("Cache Sanity:\n");
    } else {
        print("Cache Stats:\n");
    }
    foreach $mode (@Modes) {
        print "Mode $mode\n";
        if( $mode ne 'T' ) {
            $dStall{'T'}    += $dStall{$mode};
            $iStall{'T'}    += $iStall{$mode};
            $dMiss{'T'}     += $dMiss{$mode};
            $iMiss{'T'}     += $iMiss{$mode};
            $iCount{'T'}    += $iCount{$mode};
            $pcSamples{'T'} += $pcSamples{$mode};
            $upgrades{'T'}  += $upgrades{$mode};
        }
        $countCycles = $iCount{$mode} + $iStall{$mode} + $dStall{$mode};
        $sampCycles  = $pcSamples{$mode} * $pcSampleRate;
        if( $opt_c ) {
            printf("dStall %10d dMiss * memCycleTime %10d Diff %.2f%%\n",
                   $dStall{$mode}, 
                   $dMiss{$mode} * $memCycleTime,
                   $dStall{$mode} ?
                   100*($dStall{$mode} - 
                        ($dMiss{$mode}*$memCycleTime))/$dStall{$mode} :
                   0 );
            printf("iStall %10d iMiss * memCycleTime %10d Diff %.2f%%\n",
                   $iStall{$mode}, 
                   $iMiss{$mode} * $memCycleTime,
                   $iStall{$mode} ?
                   100*($iStall{$mode} -
                        ($iMiss{$mode} * $memCycleTime))/$iStall{$mode} :
                   0 );
            print "Cycles: ",
            $countCycles,
            " measured ",
            $sampCycles;
            printf(" sampled Diff %.2f%%\n",
                   $countCycles ?
                   100*( $countCycles - $sampCycles )/$countCycles :
                   0 );
        } else {
            print (($pcSamples{$mode} * $pcSampleRate) / 
                   ($cpuClock * 1000 * 1000 ));
            print " sec (sim) $iCount{$mode} instr\n";
            print "dMisses $dMiss{$mode} iMisses $iMiss{$mode} Upgrades $upgrades{$mode}\n";
            print "TotalMiss ";
            print $dMiss{$mode} + $iMiss{$mode};
            print " countCycles $countCycles sampCycles $sampCycles\n";
        }
    }
}

print ("INT $cur{'exc_int'} MOD $cur{'exc_mod'} RMISS $cur{'exc_rmiss'} WMISS $cur{'exc_wmiss'} SYSCALL $cur{'exc_syscall'} ~CLK $cur{'clkCount'}\n");

print $cur{'pctcLine'};

__END__

            print (($pcSamples{$mode} * $pcSampleRate) / 
                   ($cpuClock * 1000 * 1000 ));
            print " sec (sim) $iCount{$mode} instr\n";
            print "dMisses $dMiss{$mode} dMissStall ";
            print $dMiss{$mode} * $memCycleTime;
            print " dStall $dStall{$mode} Upgrades $upgrades{$mode}\n";
            print "iMisses $iMiss{$mode} iMissStall ";
            print $iMiss{$mode} * $memCycleTime;
            print " iStall $iStall{$mode}\n";
            print "countCycles $countCycles sampCycles $sampCycles\n";

EM_CPU 0 Cycle 33556000 PC 0x6010172c RA 0x60014120 Proc 
EM_T Tran 8.114s/59843b/209697i   TC 43t/1i/41k/0f
EM_C0 EXC 10716 INT 554 MOD 493 RMISS 1867/4684 WMISS 557/603  SYS 1936
EM_MMU (i/s/x) 0 3780765 5368383
EM_PCTC(in/ct/lk/bdr)(lk/ms) 40176 0.032% 369366 16.200% 5.318%  56543 81.503%

EM_QC V/P(i/s/x) 1690774 5250032 972072 587481 4661381 642263