Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
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 ==========================
