⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 seqsuifspec95.prl

📁 一个用在mips体系结构中的操作系统
💻 PRL
字号:
#!/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. ## possible -o options: [std|perl]# ET - Feb 1996#  Options:#   -a = print out ALL buckets i.e. separation into #        USER/KERNEL/UTLB.  Default is off#   -r = RAW data, i.e. no percentage miss rates... just absolute#        numbers#   -m = with RAW -r option, prints out [at moment] cold misses from MIPSY#   -e = take a criteria as in seqsuifstat.prl, except accumulate the#        raw numbers into a single bucket which matches the criteria!#        Then print the raw numbers in a transposed matrix version#   -w = with -e option, allows individual steps to be "weighted" so#        as to make a MIPSY window representative of the entire execution#        one argument must be passed to -w which is a Perl format#        array of numbers indicating the relative multipliers to be applied#        to each "step" which matches the -e criteria.  If the length of#        the array is a factor of the number of steps which match, then#        the multiplicative factor is just cycled over the steps according#        to the array.  It is an error if the length of the array is#        NOT a factor of the number of steps which match.require "getopts.pl";$g_numSteps = 0;$g_fieldWidth = 10;$g_mipsyData = 0;@g_steps = ();@g_matchRefs = ();  # array of refs to the hashes containing the data@k_stdFields = ('seconds', 'dL2MR', 'iL2MR', 'dTlbMR', 'iTlbMR');# k_everyField is the fields which embra and mipsy have in common# so we can compare them...@k_everyField = ('_cycles', '_instr', 'dL2Miss', 'iL2Miss', 		 'dTlb', 'iTlb', 'dStall', 'dL2Stall', 'iStall', 'iL2Stall');@k_xtraStepFields = ('UserPct', 'KernelPct', 'UTlbPct', 'avgUTlb');@k_rawdataFields = ('seconds', '_cycles', '_instr', 'dL2MR', 'iL2MR',		    'dTlbMR', 'iTlbMR', 'KernelIPct', 'UTlbIPct');@k_mipsyrawdataFields = ('cold');$definedModes{'kernel'} = 1;$definedModes{'user'} = 1;$definedModes{'idle'} = 1;$definedModes{'sync'} = 1;&doMain;sub doMain {    &GetOptions;  # get input file, output file etc    ParseFile($inputFile, "ModesFilter", 0);    # First add things up for the std user/kernel/idle    $numModes=0;    foreach $mode (keys %modes) {	$modesT[$numModes] = $mode;	$numModes++;    }    $modesT[$numModes] = 'total';    $data{"total"}{'bucketName'} = "total";    if ( defined( $opt_e ) ) {	$data{$g_everyThing}{'bucketName'} = $g_everyThing;	if ($g_allBuckets) {	    foreach $m (('USER', 'KERNEL', 'UTLB')) {		$data{$g_everyThing . "[$m]"}{'bucketName'} = $g_everyThing . "[$m]";	    }	}    }    foreach $mode (keys %modes) {	AddToBucket($data{$mode},$data{'total'});    }    foreach $mode (keys %modes) {	ComputeDerivedFields($data{$mode});    }    ComputeDerivedFields($data{'total'});    # Now create totals for the steps (i.e. combine    # USER/KERNEL/UTLB into 1    my ($stepName, $sn, $modeName);    if ($g_numSteps > 0) {	for $sn (0 .. $g_numSteps) {	    $stepName = $g_steps[$sn] . "-" . $sn;	    $data{$stepName}{'bucketName'} = $stepName; 	    foreach $modeName (('USER', 'KERNEL', 'UTLB')) {		my $buckName = $stepName . "-" . $modeName;		&AddToBucket($data{$stepName . "-" . $modeName}, 			     $data{$stepName});		if ( defined( $opt_e ) ) {		    # then we want to add this bucket if it matches the		    # criteria		    if ( &MatchCriteria( $g_steps[$sn], $sn, $modeName ) != -1) {			&AddToBucket($data{$buckName}, 				     $data{$g_everyThing});			if ($g_allBuckets) {			    # then we need to add this bucket into the appropriate			    # everything.kernel, .user, .utlb etc			    &AddToBucket($data{$buckName},					 $data{$g_everyThing . "[$modeName]"});			}			push(@g_matchRefs, $buckName );		    }		}	    }	}	# Now compute derived fields for the steps	# WARNING! Make certain you compute derived fields AFTER	# adding buckets together, because compute derived will	# insert -1.0 in places where there is missing data		# Find out where first time stamp is for "steps"	# so we can check against this in our sanity check		my $p = $data{$g_steps[0]."-0"};	$timeStamp = $p->{'time'} - ($p->{'instrCount'} + $p->{'dL2Stall'} +				     $p->{'dUpgradeStall'} + $p->{'iL2Stall'});	for $sn (0 .. $g_numSteps) {	    $stepName = $g_steps[$sn] . "-" . $sn;	    foreach $modeName (('USER', 'KERNEL', 'UTLB')) {		$buckName = $stepName . "-" . $modeName;		&ComputeDerivedFields($data{$buckName});	    }	    &ComputeDerivedFields($data{$stepName});	    # ComputeDerivedFields MUST have been called before calling	    # ComputeStepDerivedFields	    &ComputeStepDerivedFields($data{$stepName});	    # Just do the sanity check for the step as a whole	    &SanityCheck($sn);	    $timeStamp = $data{$stepName}{'time'};	}    }    # Calculate derived fields for $g_everyThing field if required    if (defined($opt_e)) {	&ComputeDerivedFields($data{$g_everyThing});	if ($g_allBuckets) {	    foreach $m (('USER','KERNEL','UTLB')) {		&ComputeDerivedFields($data{$g_everyThing . "[$m]"});	    }	}    }    # Now we start printing out!!!        if ( ! $g_everyThing ) {	&PrintStepTable;    }    else {	&PrintEveryThingTable;    }}sub PrintStepTable {    my ($stepName, $sn, $modeName);    print "TABLE_START";    if ($opt_r) { print " -r"; }    if ($opt_a) { print " -a"; }    if ($opt_m) { print " -m"; }    if ($opt_e) { print " -e"; }    print "\n";    printf("%-22s ","");        my (@derivedFields, @xtraStepFields);    if (! $g_rawData) {	@derivedFields = @k_stdFields;	@stepFields = (@derivedFields, @k_xtraStepFields);    }    else {	@derivedFields = @k_rawdataFields;	if ($g_mipsyData) {	    @stepFields = (@derivedFields, @k_mipsyrawdataFields);	}         else {            @stepFields = @derivedFields;        }    }    foreach $fd (@stepFields) {	printf("%-".$g_fieldWidth ."s ", $fd);    }    printf("\n");    printf("%s\n", "-" x (22+$g_fieldWidth*scalar(@stepFields)));###################################################################    if ($g_numSteps > 0) {	for $sn (0 .. $g_numSteps) {	    if ($g_allBuckets) {		foreach $modeName (('USER', 'KERNEL', 'UTLB')) {		    $buckName = $g_steps[$sn] . "-" . $sn . "-" . $modeName;		    PrintStep($buckName, \@derivedFields);		}	    }	    else {		$buckName = $g_steps[$sn] . "-" . $sn;		PrintStep($buckName, \@stepFields);	    }	}    }    printf("%s\n", "-" x (22+$g_fieldWidth*scalar(@stepFields)));    # OK let's print out kernel, user etc totals since we have    # them anyway    foreach $mode (keys %modes) {	PrintStep($mode, \@derivedFields);    }    PrintStep("total", \@derivedFields);}sub PrintEveryThingTable {    # Prints out a single step for ALL modes, USER/KERNEL/UTLB    my ($stepName, $sn, $modeName);    if (! $g_breakDown) {	if ($g_allBuckets) {	    foreach $m (('USER','KERNEL','UTLB')) {		&PrintEveryTable( $g_everyThing . "[$m]");	    }	}	else {	    &PrintEveryTable( $g_everyThing );	}    }    else {	foreach $ref (@g_matchRefs) {	    &PrintEveryTable( $ref );	}    }}sub PrintEveryTable {    my $sName = shift;    print "TABLE_START";    if ($opt_r) { print " -r"; }    if ($opt_a) { print " -a"; }    if ($opt_m) { print " -m"; }    if ($opt_e) { print " -e"; }    print "\n";    print "Criteria = $sName\n";    print " " x 22 . $config{'StartCPU'} . "\n";    print "-" x 30 . "\n";    foreach $i (@k_everyField) { 	PrintCount($sName, $i);    }    print "-" x 30 . "\n\n";}sub PrintCount {    my $name = shift;    my $field = shift;    my $x;    printf( "%-20s:",$field);    if( defined($format{$field})) {	$x = sprintf("$format{$name}",$data{$name}{$field});    } else { 	$x = $data{$name}{$field};    }    printf("%12s\n", $x);}sub GetOptions {    &Getopts('abmre:i:o:w:');    if( defined($opt_i) ) {       # input file	$inputFile = $opt_i;    } else {	$inputFile = "cpu.log";    }    if( defined($opt_o) ){        # output file	$output = $opt_o;    } else { 	$output = "";    }    if ( defined( $opt_a ) ) {    # allBuckets => USER/KERNEL/UTLB	$g_allBuckets = 1;    }    else {	$g_allBuckets = 0;    }    if ( defined( $opt_r ) ) {    # raw counts!	if ( defined($opt_m) ) {  # Can only specify -m with -r	    $g_mipsyData = 1;	}	$g_rawData = 1;	$g_fieldWidth = 12;    }    else {	$g_rawData = 0;    }    if ( defined( $opt_e ) ) {   # everything => print out all fields!	$g_everyThing = $opt_e;  # opt_e is the criteria argument	$g_criteria = $g_everyThing;	$g_criteria =~ s/#stepName#/\$g_name/g;	$g_criteria =~ s/#stepChronos#/\$g_chronos/g;	$g_criteria =~ s/#stepMode#/\$g_mode/g;	if (defined( $opt_b ) ) {  # b for breakdown???	    $g_breakDown = $opt_b;	}	if (defined( $opt_w ) ) {  # w => weighting factors come into play	    if ( ! ($opt_w =~ /\([0-9\.]+(,[0-9\.]+)*\)/ ) ) {		print STDERR "Invalid argument for -w.  Must be a Perl array of numbers!!\n";		@g_weights = (1);	    }	    else {		@g_weights = eval $opt_w;	    }	}    }    if (defined($ENV{'SIMTOOLS'}) ) { 	$xx = "$ENV{'SIMTOOLS'}/apps/scripts";	print STDERR "Add $xx to search path\n";	unshift(@INC,$xx);    } else { 	print STDERR "SIMTOOLS is not an environment variable \n";    }    require "simos-lib.prl";}sub PrintLine {    my $i;    my $mode;    foreach $i (0..$numModes-1) {        $mode = $modesT[$i];        printf("%12s ",$x{$mode});    }      printf("| %12s\n",$x{$modesT[$numModes]});}    sub PrintStep {    my $name = shift;    my $fields_ptr = shift;    my $i;    my $val;    # Start by printing the name of the step    printf( "%-22s:",$name);    # Then go through each passed in field to be printed...    foreach $i (0..$#$fields_ptr) {	$field = $$fields_ptr[$i];        if (defined($data{$name}{$field})) {	    if( defined($format{$field})) {		$val = sprintf("$format{$field}",$data{$name}{$field});	    } else { 		$val = $data{$name}{$field};	    }			# 	    printf("%-".$g_fieldWidth."s ", $val);	}	else {	    printf("%12s", " ");	}    }    printf("\n");}sub ModesFilter {     my $name = shift;    if( defined($definedModes{$name})) {        if (!defined($modes{$name})) {             $modes{$name} = 1;            $numModes++;            }        return $name;    }     elsif ($name =~ /(\w+)-(\d+)-(USER|KERNEL|UTLB)/) {	# Got a step function name	# DON'T add into the %modes hash, because otherwise	# we will include it in the "TOTALs".  Only	# want to print out the actual numbers	if ($2 > $g_numSteps+1) {	    print STDERR "ModesFilter ERROR: Steps not consecutively numbered\n";	}	else {	    $g_numSteps = $2;	}	if (! defined( $g_steps[$2] ) ) {	    $g_steps[$2] = $1;  	}	elsif ($g_steps[$2] ne $1) {	    print STDERR "ModesFilter ERROR: Two same numbered steps with different names!\n";	}	return $name;    }    else {         return "";    }}sub SanityCheck {    my $sn = shift;  # First parameter is the step number to sanity check    my $last_time;    my ($prev_buckname, $buckname);    if ($sn == 0) {	$buckname = $g_steps[$sn] . "-" . $sn;	if ( $data{$buckname}{'_cycles'} != $data{$buckname}{'time'}) {	    print STDERR "SanityCheck: Timestamps don't match with cycles (diff = " . ($data{$buckname}{'time'} - $data{$buckname}{'_cycles'}) . ") for sn = $sn!\n";	}    }    else {	$prev_buckname = $g_steps[$sn-1] . "-" . ($sn-1);	$buckname = $g_steps[$sn]. "-" . $sn;	$last_time = $data{$prev_buckname}{'time'};	if ( ($last_time + $data{$buckname}{'_cycles'}) != 	    $data{$buckname}{'time'}) {	    print STDERR "SanityCheck: Timestamps don't match with cycles (diff = " . ($data{$buckname}{'time'} - ($last_time + $data{$buckname}{'_cycles'})) . ") for sn = $sn!\n";	}    }}sub ComputeStepDerivedFields {    my $f = shift;   # The step bucket - DON'T PASS one of the individual				# user/kernel/utlb buckets!				# ALSO, ComputeDerivedFields should				# have already been called on these!        my $name = $f->{'bucketName'};    my $user = $data{$name . "-USER"};    my $kernel = $data{$name . "-KERNEL"};    my $utlb = $data{$name . "-UTLB"};    # OK, first step is to compute % time spent in user/kernel/utlb    # as a pct of total time for bucket...    if ($f->{'_cycles'} != 0) {	$f->{'UserPct'} = 100*$user->{'_cycles'} / $f->{'_cycles'};	$f->{'KernelPct'} = 100*$kernel->{'_cycles'} / $f->{'_cycles'};	$f->{'UTlbPct'} = 100*$utlb->{'_cycles'} / $f->{'_cycles'};    }    else {	$f->{'UserPct'} = -1.0;	$f->{'KernelPct'} = -1.0;	$f->{'UTlbPct'} = -1.0;    }    if ($f->{'_instr'} != 0) {	$f->{'UserIPct'} = 100*$user->{'_instr'} / $f->{'_instr'};	$f->{'KernelIPct'} = 100*$kernel->{'_instr'} / $f->{'_instr'};	$f->{'UTlbIPct'} = 100*$utlb->{'_instr'} / $f->{'_instr'};    }    else {	$f->{'UserIPct'} = -1.0;	$f->{'KernelIPct'} = -1.0;	$f->{'UTlbIPct'} = -1.0;    }    # Should check for UTLB numbers being approximately right...    # i.e. by taking dTLB,iTLB numbers together and computing    # avg tlb miss time    if (($user->{'dTlb'} + $user->{'iTlb'}) != 0) {	$f->{'avgUTlb'} = $utlb->{'_cycles'} / ($user->{'dTlb'} + $user->{'iTlb'});    }    else {	$f->{'avgUTlb'} = -1.0;    }}sub MatchCriteria {    # Pass the bucket name, chronos and mode    # If this matches the criteria passed on the command line    # then return 1, otherwise return -1    my ($lname, $lchronos, $lmode) = @_;    $g_name = $lname; $g_chronos = $lchronos;    $g_mode = $lmode;    # Only necessary because perl5 falls over on trying to access    # local variables in an eval script...    $result = eval($g_criteria);    if (! defined($result)) {	print STDERR "Error in evaluation string: $@\n";	return -1;    }    else {	if ($result) {	    return 1;	}	else {	    return -1;	}    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -