changeset 38:17d20e5cf924

measures coreloop and masterVP times
author Me
date Tue, 07 Sep 2010 18:40:57 -0700
parents e69579a0e797
children 8e0c881cf529 1df8d7f2c9b1
files CoreLoop.c Histogram/Histogram.c Histogram/Histogram.h MasterLoop.c VMS.c VMS.h
diffstat 6 files changed, 251 insertions(+), 52 deletions(-) [+]
line diff
     1.1 --- a/CoreLoop.c	Wed Sep 01 08:23:39 2010 -0700
     1.2 +++ b/CoreLoop.c	Tue Sep 07 18:40:57 2010 -0700
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright 2010  OpenSourceCodeStewardshipFoundation
     1.6 + * Copyright 2010  OpenSourceStewardshipFoundation
     1.7   *
     1.8   * Licensed under BSD
     1.9   */
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/Histogram/Histogram.c	Tue Sep 07 18:40:57 2010 -0700
     2.3 @@ -0,0 +1,95 @@
     2.4 +/*
     2.5 + *  Copyright 2010 OpenSourceStewardshipFoundation.org
     2.6 + *  Licensed under GNU General Public License version 2
     2.7 + *
     2.8 + * Author: seanhalle@yahoo.com
     2.9 + *
    2.10 + */
    2.11 +
    2.12 +#include "Histogram.h"
    2.13 +#include <malloc.h>
    2.14 +
    2.15 +
    2.16 +/*This Histogram Abstract Data Type has a number of bins plus a range of
    2.17 + * values that the bins span, both chosen at creation.
    2.18 + *
    2.19 + *One creates a Histogram instance using the makeHistogram function, then
    2.20 + * updates it with the addToHist function, and prints it out with the
    2.21 + * printHist function.
    2.22 + *
    2.23 + *Note, the bin width is an integer, so the end of the range is adjusted
    2.24 + * accordingly.  Use the bin-width to calculate the bin boundaries.
    2.25 + */
    2.26 +
    2.27 +
    2.28 +Histogram *
    2.29 +makeHistogram( int numBins, int startOfRange, int endOfRange )
    2.30 + {
    2.31 +   Histogram *hist;
    2.32 +   int i;
    2.33 +
    2.34 +   hist = malloc( sizeof(Histogram) );
    2.35 +   hist->bins = malloc( numBins * sizeof(int) );
    2.36 +
    2.37 +   hist->numBins      = numBins;
    2.38 +   hist->binWidth     = (endOfRange - startOfRange) / numBins;
    2.39 +   hist->endOfRange   = startOfRange + hist->binWidth * numBins;
    2.40 +   hist->startOfRange = startOfRange;
    2.41 +
    2.42 +   for( i = 0; i < hist->numBins; i++ )
    2.43 +    {
    2.44 +      hist->bins[ i ] = 0;
    2.45 +    }
    2.46 +
    2.47 +   return hist;
    2.48 + }
    2.49 +
    2.50 +void
    2.51 +addToHist( int value, Histogram *hist )
    2.52 + {
    2.53 +   int binIdx;
    2.54 +
    2.55 +   if( value < hist->startOfRange )
    2.56 +    { binIdx = 0;
    2.57 +    }
    2.58 +   else if( value > hist->endOfRange )
    2.59 +    { binIdx = hist->numBins - 1;
    2.60 +    }
    2.61 +   else
    2.62 +    {
    2.63 +      binIdx = (value - hist->startOfRange) / hist->binWidth;
    2.64 +    }
    2.65 +
    2.66 +   hist->bins[ binIdx ] += 1;
    2.67 + }
    2.68 +
    2.69 +void
    2.70 +printHist( Histogram *hist )
    2.71 + {
    2.72 +   int binIdx, i, numBars, maxHeight, barValue, binStart, binEnd;
    2.73 +
    2.74 +   maxHeight = 0;
    2.75 +   for( i = 0; i < hist->numBins; i++ )
    2.76 +    {
    2.77 +      if( maxHeight < hist->bins[ i ] ) maxHeight = hist->bins[ i ];
    2.78 +    }
    2.79 +   barValue = maxHeight / 60;  //60 spaces across page for tallest bin
    2.80 +
    2.81 +   printf("histogram: \n");
    2.82 +   if( barValue == 0 ) printf("error printing histogram\n");
    2.83 +   for( binIdx = 0; binIdx < hist->numBins; binIdx++ )
    2.84 +    {
    2.85 +      binStart = hist->startOfRange + hist->binWidth * binIdx;
    2.86 +      binEnd = binStart + hist->binWidth;
    2.87 +      printf("bin range: %d - %d", binStart, binEnd );
    2.88 +
    2.89 +      numBars = hist->bins[ binIdx ] / barValue;
    2.90 +         //print one bin, height of bar is num dashes across page
    2.91 +      for( i = 0; i < numBars; i++ )
    2.92 +       {
    2.93 +         printf("-");
    2.94 +       }
    2.95 +      printf("\n");
    2.96 +    }
    2.97 + }
    2.98 +
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/Histogram/Histogram.h	Tue Sep 07 18:40:57 2010 -0700
     3.3 @@ -0,0 +1,33 @@
     3.4 +/*
     3.5 + *  Copyright 2010 OpenSourceStewardshipFoundation.org
     3.6 + *  Licensed under GNU General Public License version 2
     3.7 + *
     3.8 + * Author: seanhalle@yahoo.com
     3.9 + *
    3.10 + */
    3.11 +
    3.12 +
    3.13 +#ifndef _HISTOGRAM_H
    3.14 +#define	_HISTOGRAM_H
    3.15 +
    3.16 +typedef struct
    3.17 + {
    3.18 +   int  startOfRange;
    3.19 +   int  endOfRange;
    3.20 +   int  numBins;
    3.21 +   int  binWidth;
    3.22 +   int *bins;
    3.23 + }
    3.24 +Histogram;
    3.25 +
    3.26 +Histogram *
    3.27 +makeHistogram( int numBins, int startOfRange, int endOfRange );
    3.28 +
    3.29 +void
    3.30 +addToHist( int value, Histogram *hist );
    3.31 +
    3.32 +void
    3.33 +printHist( Histogram *hist );
    3.34 +
    3.35 +#endif	/* _HISTOGRAM_H */
    3.36 +
     4.1 --- a/MasterLoop.c	Wed Sep 01 08:23:39 2010 -0700
     4.2 +++ b/MasterLoop.c	Tue Sep 07 18:40:57 2010 -0700
     4.3 @@ -1,5 +1,5 @@
     4.4  /*
     4.5 - * Copyright 2010  OpenSourceCodeStewardshipFoundation
     4.6 + * Copyright 2010  OpenSourceStewardshipFoundation
     4.7   *
     4.8   * Licensed under BSD
     4.9   */
    4.10 @@ -98,6 +98,14 @@
    4.11  
    4.12     
    4.13     masterLoopStartPt:
    4.14 +   //============================= MEASUREMENT STUFF ========================
    4.15 +   #ifdef MEAS__TIME_MASTER
    4.16 +      //Total Master time includes one coreloop time -- just assume the core
    4.17 +      // loop time is same for Master as for AppVPs, even though it will be
    4.18 +      // smaller due to high predictability of the jumps.
    4.19 +   saveLowTimeStampCountInto( masterPr->startMasterTSCLow );
    4.20 +   #endif
    4.21 +   //========================================================================
    4.22  
    4.23     masterEnv        = _VMSMasterEnv;
    4.24     
    4.25 @@ -156,6 +164,13 @@
    4.26     coreLoopFramePtr  = masterPr->coreLoopFramePtr;//need this only
    4.27     coreLoopStackPtr  = masterPr->coreLoopStackPtr;//shouldn't need -- safety
    4.28     
    4.29 +   #ifdef MEAS__TIME_MASTER
    4.30 +   saveLowTimeStampCountInto( masterPr->endMasterTSCLow );
    4.31 +      int  diff = masterPr->endMasterTSCLow - masterPr->startMasterTSCLow;
    4.32 +      if( diff > 1000000 ) diff = 0;
    4.33 +      addToHist( diff, masterEnv->measMasterHist );
    4.34 +   #endif
    4.35 +
    4.36     asm volatile("movl %0,     %%eax;  \
    4.37                   movl %%esp, (%%eax); \
    4.38                   movl %1,     %%eax;  \
    4.39 @@ -167,7 +182,7 @@
    4.40                   movl $0x0, (%%ebx);  \
    4.41                   jmp  %%eax;"         \
    4.42     /* outputs */ : "=g" (stackPtrAddr), "=g" (framePtrAddr),                \
    4.43 -                   "=g"(masterLockAddr)                                   \
    4.44 +                   "=g"(masterLockAddr)                                     \
    4.45     /* inputs  */ : "g" (jmpPt), "g"(coreLoopStackPtr), "g"(coreLoopFramePtr)\
    4.46     /* clobber */ : "memory", "%eax", "%ebx", "%ecx", "%edx", "%edi", "%esi" \
    4.47                  );//can probably make clobber list empty -- but safe for now
     5.1 --- a/VMS.c	Wed Sep 01 08:23:39 2010 -0700
     5.2 +++ b/VMS.c	Tue Sep 07 18:40:57 2010 -0700
     5.3 @@ -1,5 +1,5 @@
     5.4  /*
     5.5 - * Copyright 2010  OpenSourceCodeStewardshipFoundation
     5.6 + * Copyright 2010  OpenSourceStewardshipFoundation
     5.7   *
     5.8   * Licensed under BSD
     5.9   */
    5.10 @@ -10,6 +10,7 @@
    5.11  
    5.12  #include "VMS.h"
    5.13  #include "Queue_impl/BlockingQueue.h"
    5.14 +#include "Histogram/Histogram.h"
    5.15  
    5.16  
    5.17  #define thdAttrs NULL
    5.18 @@ -126,6 +127,17 @@
    5.19     // in the master, taking from this massive chunk.
    5.20  
    5.21  //   initFreeList();
    5.22 +
    5.23 +   //============================= MEASUREMENT STUFF ========================
    5.24 +   #ifdef MEAS__TIME_STAMP_SUSP
    5.25 +   _VMSMasterEnv->measSuspHist   = makeHistogram( 25, 110, 135 );
    5.26 +   #endif
    5.27 +
    5.28 +   #ifdef MEAS__TIME_MASTER
    5.29 +   _VMSMasterEnv->measMasterHist = makeHistogram( 25, 500, 800 );
    5.30 +   #endif
    5.31 +   //========================================================================
    5.32 +
    5.33   }
    5.34  
    5.35  /*
    5.36 @@ -293,6 +305,7 @@
    5.37     newPr->nextInstrPt = fnPtr;
    5.38     newPr->initialData = initialData;
    5.39     newPr->requests    = NULL;
    5.40 +   newPr->schedSlot   = NULL;
    5.41  //   newPr->coreLoopStartPt = _VMSMasterEnv->coreLoopStartPt;
    5.42  
    5.43        //fnPtr takes two params -- void *initData & void *animProcr
    5.44 @@ -324,7 +337,7 @@
    5.45   * next work-unit for that procr.
    5.46   */
    5.47  void
    5.48 -VMS__suspend_procr( VirtProcr *callingPr )
    5.49 +VMS__suspend_procr( VirtProcr *animatingPr )
    5.50   { void *jmpPt, *stackPtrAddr, *framePtrAddr, *coreLoopStackPtr;
    5.51     void *coreLoopFramePtr;
    5.52  
    5.53 @@ -332,21 +345,19 @@
    5.54        // scheduled again at some future point -- to resume, core loop jumps
    5.55        // to the resume point (below), which causes restore of saved regs and
    5.56        // "return" from this call.
    5.57 -   callingPr->nextInstrPt = &&ResumePt;
    5.58 +   animatingPr->nextInstrPt = &&ResumePt;
    5.59  
    5.60        //return ownership of the virt procr and sched slot to Master virt pr
    5.61 -   callingPr->schedSlot->workIsDone = TRUE;
    5.62 +   animatingPr->schedSlot->workIsDone = TRUE;
    5.63  //   coreIdx = callingPr->coreAnimatedBy;
    5.64  
    5.65 -   stackPtrAddr      = &(callingPr->stackPtr);
    5.66 -   framePtrAddr      = &(callingPr->framePtr);
    5.67 +   stackPtrAddr      = &(animatingPr->stackPtr);
    5.68 +   framePtrAddr      = &(animatingPr->framePtr);
    5.69  
    5.70     jmpPt             = _VMSMasterEnv->coreLoopStartPt;
    5.71 -   coreLoopFramePtr  = callingPr->coreLoopFramePtr;//need this only
    5.72 -   coreLoopStackPtr  = callingPr->coreLoopStackPtr;//shouldn't need -- safety
    5.73 +   coreLoopFramePtr  = animatingPr->coreLoopFramePtr;//need this only
    5.74 +   coreLoopStackPtr  = animatingPr->coreLoopStackPtr;//safety
    5.75  
    5.76 -      //Eclipse's compilation sequence complains -- so break into two
    5.77 -      // separate in-line assembly pieces
    5.78        //Save the virt procr's stack and frame ptrs,
    5.79     asm volatile("movl %0,     %%eax;  \
    5.80                   movl %%esp, (%%eax); \
    5.81 @@ -357,6 +368,16 @@
    5.82     /* clobber */ : "%eax" \
    5.83                  );
    5.84  
    5.85 +   #ifdef MEAS__TIME_STAMP_SUSP
    5.86 +      //record time stamp into animating procr: compared to time-stamp
    5.87 +      // recorded below, at the resume pt.
    5.88 +      //NOTE: doing minimal work here 'cause only a few instrs executed in
    5.89 +      // core loop, so only using bottom half of time-stamp -- have to
    5.90 +      // externally do sanity check & throw out absurd values due to rollover
    5.91 +
    5.92 +   saveLowTimeStampCountInto( animatingPr->preSuspTSCLow );
    5.93 +   #endif
    5.94 +
    5.95        //restore coreloop's frame ptr, then jump back to "start" of core loop
    5.96        //Note, GCC compiles to assembly that saves esp and ebp in the stack
    5.97        // frame -- so have to explicitly do assembly that saves to memory
    5.98 @@ -372,18 +393,23 @@
    5.99                     // assembly, so that stack pointer is correct, before jmp
   5.100  
   5.101  ResumePt:
   5.102 +   #ifdef MEAS__TIME_STAMP_SUSP
   5.103 +   saveLowTimeStampCountInto( animatingPr->postSuspTSCLow );
   5.104 +      //Take difference between the pre-suspend and post-suspend times
   5.105 +      // and do sanity check to see if rollover happened between
   5.106 +   int  diff = animatingPr->postSuspTSCLow - animatingPr->preSuspTSCLow;
   5.107 +   if( diff > 1000000 ) diff = 0;
   5.108 +   addToHist( diff, _VMSMasterEnv->measSuspHist );
   5.109 +
   5.110 +   #endif
   5.111 +
   5.112     return;
   5.113   }
   5.114  
   5.115  
   5.116  
   5.117  
   5.118 -/*Not sure yet the form going to put "dissipate" in, so this is the third
   5.119 - * possibility -- the semantic layer can just make a macro that looks like
   5.120 - * a call to its name, then expands to a call to this.
   5.121 - *
   5.122 - *As of June 30, 2010  this looks like the top choice..
   5.123 - *
   5.124 +/*
   5.125   *This adds a request to dissipate, then suspends the processor so that the
   5.126   * request handler will receive the request.  The request handler is what
   5.127   * does the work of freeing memory and removing the processor from the
   5.128 @@ -433,32 +459,8 @@
   5.129   }
   5.130  
   5.131  
   5.132 -
   5.133 -//TODO: add a semantic-layer supplied "freer" for the semantic-data portion
   5.134 -// of a request -- IE call with both a virt procr and a fn-ptr to request
   5.135 -// freer (or maybe put request freer as a field in virt procr?)
   5.136 -void
   5.137 -VMS__remove_and_free_top_request( VirtProcr *procrWithReq )
   5.138 - { VMSReqst *req;
   5.139 -
   5.140 -   req = procrWithReq->requests;
   5.141 -   if( req == NULL ) return;
   5.142 -   procrWithReq->requests = procrWithReq->requests->nextReqst;
   5.143 -   VMS__free_request( req );
   5.144 - }
   5.145 -
   5.146 -
   5.147 -//TODO: add a semantic-layer supplied "freer" for the semantic-data portion
   5.148 -// of a request -- IE call with both a virt procr and a fn-ptr to request
   5.149 -// freer (also maybe put sem request freer as a field in virt procr?)
   5.150 -//SSR relies right now on this only freeing VMS layer of request -- the
   5.151 -// semantic portion of request is alloc'd and freed by request handler
   5.152 -void
   5.153 -VMS__free_request( VMSReqst *req )
   5.154 - { 
   5.155 -   free( req );
   5.156 - }
   5.157 -
   5.158 +/*Use this to get first request before starting request handler's loop
   5.159 + */
   5.160  VMSReqst *
   5.161  VMS__take_top_request_from( VirtProcr *procrWithReq )
   5.162   { VMSReqst *req;
   5.163 @@ -470,18 +472,36 @@
   5.164     return req;
   5.165   }
   5.166  
   5.167 +/*A subtle bug due to freeing then accessing "next" after freed caused this
   5.168 + * form of call to be put in -- so call this at end of request handler loop
   5.169 + * that iterates through the requests.
   5.170 + */
   5.171  VMSReqst *
   5.172  VMS__free_top_and_give_next_request_from( VirtProcr *procrWithReq )
   5.173   { VMSReqst *req;
   5.174  
   5.175     req = procrWithReq->requests;
   5.176 -   if( req == NULL ) return req;
   5.177 +   if( req == NULL ) return NULL;
   5.178  
   5.179     procrWithReq->requests = procrWithReq->requests->nextReqst;
   5.180     VMS__free_request( req );
   5.181     return procrWithReq->requests;
   5.182   }
   5.183  
   5.184 +
   5.185 +//TODO: add a semantic-layer supplied "freer" for the semantic-data portion
   5.186 +// of a request -- IE call with both a virt procr and a fn-ptr to request
   5.187 +// freer (also maybe put sem request freer as a field in virt procr?)
   5.188 +//MeasVMS relies right now on this only freeing VMS layer of request -- the
   5.189 +// semantic portion of request is alloc'd and freed by request handler
   5.190 +void
   5.191 +VMS__free_request( VMSReqst *req )
   5.192 + {
   5.193 +   free( req );
   5.194 + }
   5.195 +
   5.196 +
   5.197 +
   5.198  inline int
   5.199  VMS__isSemanticReqst( VMSReqst *req )
   5.200   {
   5.201 @@ -508,7 +528,7 @@
   5.202   }
   5.203  
   5.204  void
   5.205 -VMS__send_register_new_procr_request(VirtProcr *newPr, VirtProcr *reqstingPr)
   5.206 +VMS__send_req_to_register_new_procr(VirtProcr *newPr, VirtProcr *reqstingPr)
   5.207   { VMSReqst *req;
   5.208  
   5.209     req                  = malloc( sizeof(VMSReqst) );
   5.210 @@ -547,7 +567,7 @@
   5.211  //TODO: implement VMS__malloc system, including "give up ownership"
   5.212  
   5.213        //The dissipate request might still be attached, so remove and free it
   5.214 -   VMS__remove_and_free_top_request( animatingPr );
   5.215 +   VMS__free_top_and_give_next_request_from( animatingPr );
   5.216  
   5.217        //NOTE: initialData was given to the processor, so should either have
   5.218        // been alloc'd with VMS__malloc, or freed by the level above animPr.
     6.1 --- a/VMS.h	Wed Sep 01 08:23:39 2010 -0700
     6.2 +++ b/VMS.h	Tue Sep 07 18:40:57 2010 -0700
     6.3 @@ -12,12 +12,22 @@
     6.4  
     6.5  #include "VMS_primitive_data_types.h"
     6.6  #include "Queue_impl/BlockingQueue.h"
     6.7 +#include "Histogram/Histogram.h"
     6.8  #include <pthread.h>
     6.9  
    6.10     //When DEBUG is defined, VMS does sequential exe in the main thread
    6.11     // It still does co-routines and all the mechanisms are the same, it just
    6.12     // has only a single thread and animates VPs one at a time
    6.13 -//#define DEBUG
    6.14 +#define SEQUENTIAL
    6.15 +
    6.16 +   //when MEAS__TAKE_SUSP_TSC is defined, causes code to be inserted and
    6.17 +   // compiled-in that saves the low part of the time stamp count just before
    6.18 +   // suspending a processor and just after resuming that processor.  It is
    6.19 +   // saved into a field added to VirtProcr.  Have to sanity-check for
    6.20 +   // rollover of low portion into high portion.
    6.21 +#define MEAS__TIME_STAMP_SUSP
    6.22 +#define MEAS__TIME_MASTER
    6.23 +#define MEAS__NUM_TIMES_TO_RUN 100000
    6.24  
    6.25     //This value is the number of hardware threads in the shared memory
    6.26     // machine
    6.27 @@ -59,8 +69,6 @@
    6.28   {
    6.29     void           *endThdPt;
    6.30     unsigned int    coreNum;
    6.31 -//   void           *framePtr;
    6.32 -//   void           *stackPtr;
    6.33   }
    6.34  ThdParams;
    6.35  
    6.36 @@ -109,6 +117,17 @@
    6.37     VMSReqst   *requests;
    6.38  
    6.39     void       *semanticData;
    6.40 +
    6.41 +   //============================= MEASUREMENT STUFF ========================
    6.42 +   #ifdef MEAS__TIME_STAMP_SUSP
    6.43 +   unsigned int preSuspTSCLow;
    6.44 +   unsigned int postSuspTSCLow;
    6.45 +   #endif
    6.46 +   #ifdef MEAS__TIME_MASTER
    6.47 +   unsigned int startMasterTSCLow;
    6.48 +   unsigned int endMasterTSCLow;
    6.49 +   #endif
    6.50 +   //========================================================================
    6.51   };
    6.52  //VirtProcr
    6.53  
    6.54 @@ -131,6 +150,15 @@
    6.55  
    6.56     int              setupComplete;
    6.57     int              masterLock;
    6.58 +
    6.59 +   //============================= MEASUREMENT STUFF ========================
    6.60 +   #ifdef MEAS__TIME_STAMP_SUSP
    6.61 +   Histogram   *measSuspHist;
    6.62 +   #endif
    6.63 +   #ifdef MEAS__TIME_MASTER
    6.64 +   Histogram   *measMasterHist;
    6.65 +   #endif
    6.66 +   //========================================================================
    6.67   }
    6.68  MasterEnv;
    6.69  
    6.70 @@ -176,7 +204,7 @@
    6.71  VMS__add_sem_request( void *semReqData, VirtProcr *callingPr );
    6.72  
    6.73  void
    6.74 -VMS__send_register_new_procr_request( VirtProcr *newPrToRegister,
    6.75 +VMS__send_req_to_register_new_procr( VirtProcr *newPrToRegister,
    6.76                                        VirtProcr *reqstingPr );
    6.77  
    6.78  void
    6.79 @@ -234,6 +262,14 @@
    6.80     /* clobber */ : "%eax", "%edx"         \
    6.81                  );
    6.82  
    6.83 +#define saveLowTimeStampCountInto(low)    \
    6.84 +   asm volatile("RDTSC;                   \
    6.85 +                 movl %%eax, %0;"         \
    6.86 +   /* outputs */ : "=m" (low)             \
    6.87 +   /* inputs  */ :                        \
    6.88 +   /* clobber */ : "%eax", "%edx"         \
    6.89 +                );
    6.90 +
    6.91  inline TSCount getTSCount();
    6.92  
    6.93  //===================== Debug ==========================