"Fossies" - the Fresh Open Source Software Archive

Member "heaplayers-351/benchmarks/lindsay/measure.cc" (23 Dec 2005, 9952 Bytes) of package /linux/misc/old/heaplayers_3_5_1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "measure.cc" see the Fossies "Dox" file reference documentation.

    1 // measure.c
    2 // ---------
    3 //      Copyright 1988 D.C. Lindsay at Carnegie Mellon University
    4 //
    5 // Part of Hyperswitch simulation. Does measurements & related reporting.
    6 // Assumed that there will only be one instance, so some static data.
    7 
    8 #include "node.h"
    9 #include "statistics.h"
   10 #include "histogram.h"
   11 #include "measure.h"
   12 #include "chart.h"
   13 #include <stdlib.h>
   14 #include <iostream>
   15 using namespace std;
   16 
   17 extern schedulerclass * scheduler;
   18 extern int message_trace_switch;
   19 extern int message_length;
   20 extern int cube_size;
   21 
   22 // local data ( since only one instance will exist )
   23 
   24 bool rungenerator = true;   // generate() consults this
   25 int initialmessages = 0;    // reset after this many note's.
   26 int allowedmessages = 10000;    // stop generating after this many more note's
   27 
   28 // accumulators - OK is delivered messages, FAIL is undelivered
   29 statistics OKdistance;      // across hypercube the message travelled
   30 statistics OKlatency;       // nanos from comm start to last bit in RAM
   31 statistics OKprobes;        // probes+1 comm chips got involved
   32 statistics OKprobeexcess;   // difference of probes and distance 
   33                 // ( zero when no trouble encountered )
   34 statistics OKwait;      // (if waited) time spent before seized source
   35 statistics OKretries;       // # of times message was retried
   36 statistics FAILdistance;    // across hypercube the message travelled
   37 statistics FAILlatency;     // nanos from comm start to last bit in RAM
   38 statistics FAILprobes;      // probes+1 comm chips got involved
   39 statistics FAILprobeexcess; // difference of probes and distance 
   40                 // ( zero when no trouble encountered )
   41 statistics FAILwait;        // (if waited) time spent before seized source
   42 statistics FAILretries;     // # of times message was retried
   43 
   44     // histogram is as "statistics" but note() is indexed by distance
   45 histogramclass OKlatencyhisto;
   46 histogramclass OKprobeshisto;
   47 histogramclass OKprobeexcesshisto;
   48 
   49 histogramclass FAILlatencyhisto;
   50 histogramclass FAILprobeshisto;
   51 histogramclass FAILprobeexcesshisto;
   52 
   53     // chart just counts how many times the noted value is in ranges
   54 chartclass OKlatencychart( 10000 );
   55 chartclass OKlatencychart2( 1000 );
   56 chartclass FAILlatencychart( 10000 );
   57 chartclass FAILlatencychart2( 1000 );
   58 chartclass OKprobeexcesschart( 1 );
   59 
   60 int in_messagecount = 0;    // reset() copies messagecount to here
   61 int in_postmortemcount = 0; // reset() copies postmortemcount to here
   62 int messagecount;       // # started up
   63 int postmortemcount;        // diff from messagecount is in-transit ones
   64 int completeOKcount;        // message made it thru teardown
   65 int sourcequitcount;        // message killed - all source links busy
   66 int nopathscount;
   67 int failurecount;
   68 int ignoredcount;
   69 
   70 timetype reset_time = 0;    // time measurement started
   71 /*****************************************/
   72 measureclass::measureclass()
   73 {
   74     messagecount = 0;
   75     postmortemcount = 0;
   76     completeOKcount = 0;
   77     sourcequitcount = 0;
   78     nopathscount = 0;
   79     failurecount = 0;
   80     ignoredcount = 0;
   81 }
   82 /*****************************************/
   83 static void reset()
   84 {
   85     in_messagecount = messagecount;     // keep a copy
   86     in_postmortemcount = postmortemcount;   // keep a copy
   87     messagecount = 0;
   88     postmortemcount = 0;
   89     completeOKcount = 0;
   90     sourcequitcount = 0;
   91     nopathscount = 0;
   92     failurecount = 0;
   93     ignoredcount = 0;
   94 
   95     OKdistance.reset();
   96     OKlatency.reset();
   97     OKprobes.reset();
   98     OKprobeexcess.reset();
   99     OKwait.reset();
  100     OKretries.reset();
  101 
  102     FAILdistance.reset();
  103     FAILlatency.reset();
  104     FAILprobes.reset();
  105     FAILprobeexcess.reset();
  106     FAILwait.reset();
  107     FAILretries.reset();
  108 
  109     OKlatencyhisto.reset();
  110     OKprobeshisto.reset();
  111     OKprobeexcesshisto.reset();
  112 
  113     FAILlatencyhisto.reset();
  114     FAILprobeshisto.reset();
  115     FAILprobeexcesshisto.reset();
  116 
  117     OKlatencychart.reset();
  118     OKlatencychart2.reset();
  119     FAILlatencychart.reset();
  120     FAILlatencychart2.reset();
  121     OKprobeexcesschart.reset();
  122 }
  123 
  124 /*****************************************/
  125 void measureclass::runsize( int newinitial, int newallowed )
  126 {
  127     initialmessages = newinitial;
  128     allowedmessages = newallowed;
  129 }
  130 /*****************************************/
  131 SMessagePtr  measureclass::generate()
  132 {
  133     if( rungenerator == false ) return NULLO;
  134     ++messagecount;
  135     if( TRACE ); else if((messagecount&255)==0) cout << ".";
  136     SMessagePtr smp;
  137 #ifdef REFGC
  138     smp.New();
  139 #else
  140     smp = new ( message );
  141 #endif
  142     return smp;
  143 }
  144 /*****************************************/
  145 //
  146 // Prints summary of measurements.
  147 // Only prints the first time it is called.
  148 
  149 static bool printed = false;
  150 
  151 static void print()
  152 {
  153     if( printed == true ) return;
  154     printed = true;
  155     cout    << "\nMessages completed " << postmortemcount NL;
  156 
  157     cout << " Completed ok " << completeOKcount NL;
  158     if( sourcequitcount )
  159         cout << " quit(all source links busy) " << sourcequitcount NL;
  160     if( failurecount )
  161         cout << " quit(dest busy) " << failurecount NL;
  162     if( nopathscount )
  163         cout << " quit(all paths failed) " << nopathscount NL;
  164     timetype elapsed = scheduler->clock - reset_time;
  165     cout    << "Time for " << postmortemcount << " was "
  166         << elapsed << " ns == "
  167         << (elapsed/postmortemcount) 
  168         << " ns/mesg == "
  169         << ((elapsed/postmortemcount)*cube_size)
  170         << " ns/m/node" NL;
  171 
  172     int meandistance = 
  173         OKdistance.print( "Delivered-message: Distance: " );
  174 
  175     int meantime = OKlatency.print( "Delivered-message: Latency: " );
  176     // now compute the time due to just the bandwidth limit of any link
  177     int bandtime = message_length * LINK_BANDWIDTH; 
  178     cout << "\tThis is " << 
  179         ( ((100*meantime)+(bandtime/2))/bandtime )
  180         << "% of the bandwidth latency " << bandtime NL;
  181     cout << "\t(Exceeds the bandwidth latency by " 
  182         << (meantime-bandtime)<< ")\n";
  183     // now add in the time due to link traversal (speed of light, etc)
  184     // and the time due to flowing through crossbars. This has to be
  185     // multiplied by the mean distance since it happens per-hop.
  186     bandtime += (meandistance * (LINK_LATENCY + XBAR_LATENCY));
  187     cout << "\tThis is " << 
  188         ( ((100*meantime)+(bandtime/2))/bandtime )
  189         << "% of the hardware latency " << bandtime NL;
  190     cout << "\t(Exceeds the hardware latency by " 
  191         << (meantime-bandtime)<< ")\n";
  192 
  193     OKlatencyhisto.print( " histo:" );
  194 
  195     OKprobes.print( "Delivered-message: Probes: " );
  196     OKprobeshisto.print( " histo:" );
  197 
  198     OKprobeexcess.print( "Delivered-message: Probes minus Distance: " );
  199     OKprobeexcesschart.print( " chart:" );
  200     OKprobeexcesshisto.print( " histo:" );
  201 
  202     OKretries.print( "Delivered-message: Retries: " );
  203 
  204     OKwait.print( "Delivered-message: Wait: " );
  205 
  206     OKlatencychart.print( "Delivered-message: Latency chart: " );
  207     OKlatencychart2.print( "Finer-grain Latency chart: " );
  208 
  209     FAILdistance.print( "Undelivered message: Distance: " );
  210 
  211     FAILlatency.print( "Undelivered message: Latency: " );
  212     FAILlatencyhisto.print( " histo:" );
  213 
  214     FAILprobes.print( "Undelivered message: Probes: " );
  215     FAILprobeshisto.print( " histo:" );
  216 
  217     FAILprobeexcess.print("Undelivered message: Probes minus Distance: ");
  218     FAILprobeexcesshisto.print( " histo:" );
  219 
  220     FAILretries.print( "Undelivered message: Retries: " );
  221 
  222     FAILwait.print( "Undelivered message: Wait: " );
  223 
  224     FAILlatencychart.print( "Undelivered message: Latency chart: " );
  225     FAILlatencychart2.print( "Finer grain Latency chart: " );
  226 }
  227 /*****************************************/
  228 // Accumulate statistics on a message and deallocate it.
  229 //
  230 void measureclass::note( SMessagePtr pm, finalstate reason )
  231 {
  232     postmortemcount++;
  233     switch( reason ) {
  234 case failure:       failurecount++;     break;
  235 case nopaths:       nopathscount++;     break;
  236 case sourcequit:    sourcequitcount++;  break;
  237 case completeOK:    completeOKcount++;  break;
  238 
  239 case ignored:   ignoredcount++;
  240 #ifndef REFGC
  241         delete pm;      // note, another delete below
  242 #endif
  243         return;
  244 default:    cout << "ERROR: BUG IN POSTMORTEM\n";
  245         exit(1);
  246     }
  247     if( reason == completeOK ) {
  248         OKdistance.note( pm-> distance );
  249         int latency = pm-> lastbittime - pm-> starttime;
  250         OKlatency.note( latency );
  251         OKlatencyhisto.note( latency, pm-> distance );
  252         OKlatencychart.note( latency );
  253         OKlatencychart2.note( latency );
  254         OKprobes.note( pm-> probecount );
  255         OKprobeshisto.note( pm-> probecount, pm-> distance );
  256         OKprobeexcess.note( pm-> probecount - pm-> distance );
  257         OKprobeexcesshisto.note( pm-> probecount - pm-> distance,
  258             pm-> distance );
  259         OKprobeexcesschart.note( pm-> probecount - pm-> distance );
  260         if( pm-> retrycount > 0 )
  261             OKretries.note( pm-> retrycount );
  262         int wait = pm-> activetime - pm-> starttime;
  263         if( wait > 0 ) OKwait.note( wait );
  264     }else{
  265         FAILdistance.note( pm-> distance );
  266         int latency = scheduler->clock - pm-> starttime;
  267         FAILlatency.note( latency );
  268         FAILlatencyhisto.note( latency, pm-> distance );
  269         FAILlatencychart.note( latency );
  270         FAILlatencychart2.note( latency );
  271         FAILprobes.note( pm-> probecount );
  272         FAILprobeshisto.note( pm-> probecount, pm-> distance );
  273         FAILprobeexcess.note( pm-> probecount - pm-> distance );
  274         FAILprobeexcesshisto.note( pm-> probecount - pm-> distance,
  275             pm-> distance );
  276         if( pm-> retrycount > 0 )
  277             FAILretries.note( pm-> retrycount );
  278         int wait = pm-> activetime - pm-> starttime;
  279         if( wait > 0 ) FAILwait.note( wait );
  280     }
  281 
  282 
  283 #ifndef REFGC
  284     delete pm;      // note, case ignored does its own
  285 #endif
  286     if( postmortemcount == initialmessages ){
  287         reset_time = scheduler->clock;
  288         cout << "\nResetting counts at time " << 
  289             (unsigned long) reset_time << ".\n";
  290         //          form( "%lu", reset_time ) << ".\n";
  291         reset();
  292         initialmessages = 0;    // can only reset once
  293     }else if( postmortemcount == allowedmessages ) {
  294         print();
  295         rungenerator = false;   // no need to add more mesgs to sim
  296     }
  297 }
  298 /*****************************************/
  299 void measureclass::finalize()
  300 {
  301     print();        // if already done, wont happen again
  302     int tot_messagecount = in_messagecount + messagecount;
  303     cout    << "Finalize: total run created "
  304         << tot_messagecount << " messages.\n";
  305     int tot_postmortem = in_postmortemcount + postmortemcount;
  306     int intransit = tot_messagecount - tot_postmortem;
  307     if( intransit ) cout << "ERROR ************** "
  308         << "messages still in transit " << intransit 
  309         << "***************\n";
  310 }
  311 /*****************************************/