# HG changeset patch # User Me # Date 1283910057 25200 # Node ID 17d20e5cf9242427fd7c20b894ee2204393f9ca4 # Parent e69579a0e7976d48febaa60141a53af90e760139 measures coreloop and masterVP times diff -r e69579a0e797 -r 17d20e5cf924 CoreLoop.c --- a/CoreLoop.c Wed Sep 01 08:23:39 2010 -0700 +++ b/CoreLoop.c Tue Sep 07 18:40:57 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2010 OpenSourceCodeStewardshipFoundation + * Copyright 2010 OpenSourceStewardshipFoundation * * Licensed under BSD */ diff -r e69579a0e797 -r 17d20e5cf924 Histogram/Histogram.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Histogram/Histogram.c Tue Sep 07 18:40:57 2010 -0700 @@ -0,0 +1,95 @@ +/* + * Copyright 2010 OpenSourceStewardshipFoundation.org + * Licensed under GNU General Public License version 2 + * + * Author: seanhalle@yahoo.com + * + */ + +#include "Histogram.h" +#include + + +/*This Histogram Abstract Data Type has a number of bins plus a range of + * values that the bins span, both chosen at creation. + * + *One creates a Histogram instance using the makeHistogram function, then + * updates it with the addToHist function, and prints it out with the + * printHist function. + * + *Note, the bin width is an integer, so the end of the range is adjusted + * accordingly. Use the bin-width to calculate the bin boundaries. + */ + + +Histogram * +makeHistogram( int numBins, int startOfRange, int endOfRange ) + { + Histogram *hist; + int i; + + hist = malloc( sizeof(Histogram) ); + hist->bins = malloc( numBins * sizeof(int) ); + + hist->numBins = numBins; + hist->binWidth = (endOfRange - startOfRange) / numBins; + hist->endOfRange = startOfRange + hist->binWidth * numBins; + hist->startOfRange = startOfRange; + + for( i = 0; i < hist->numBins; i++ ) + { + hist->bins[ i ] = 0; + } + + return hist; + } + +void +addToHist( int value, Histogram *hist ) + { + int binIdx; + + if( value < hist->startOfRange ) + { binIdx = 0; + } + else if( value > hist->endOfRange ) + { binIdx = hist->numBins - 1; + } + else + { + binIdx = (value - hist->startOfRange) / hist->binWidth; + } + + hist->bins[ binIdx ] += 1; + } + +void +printHist( Histogram *hist ) + { + int binIdx, i, numBars, maxHeight, barValue, binStart, binEnd; + + maxHeight = 0; + for( i = 0; i < hist->numBins; i++ ) + { + if( maxHeight < hist->bins[ i ] ) maxHeight = hist->bins[ i ]; + } + barValue = maxHeight / 60; //60 spaces across page for tallest bin + + printf("histogram: \n"); + if( barValue == 0 ) printf("error printing histogram\n"); + for( binIdx = 0; binIdx < hist->numBins; binIdx++ ) + { + binStart = hist->startOfRange + hist->binWidth * binIdx; + binEnd = binStart + hist->binWidth; + printf("bin range: %d - %d", binStart, binEnd ); + + numBars = hist->bins[ binIdx ] / barValue; + //print one bin, height of bar is num dashes across page + for( i = 0; i < numBars; i++ ) + { + printf("-"); + } + printf("\n"); + } + } + diff -r e69579a0e797 -r 17d20e5cf924 Histogram/Histogram.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Histogram/Histogram.h Tue Sep 07 18:40:57 2010 -0700 @@ -0,0 +1,33 @@ +/* + * Copyright 2010 OpenSourceStewardshipFoundation.org + * Licensed under GNU General Public License version 2 + * + * Author: seanhalle@yahoo.com + * + */ + + +#ifndef _HISTOGRAM_H +#define _HISTOGRAM_H + +typedef struct + { + int startOfRange; + int endOfRange; + int numBins; + int binWidth; + int *bins; + } +Histogram; + +Histogram * +makeHistogram( int numBins, int startOfRange, int endOfRange ); + +void +addToHist( int value, Histogram *hist ); + +void +printHist( Histogram *hist ); + +#endif /* _HISTOGRAM_H */ + diff -r e69579a0e797 -r 17d20e5cf924 MasterLoop.c --- a/MasterLoop.c Wed Sep 01 08:23:39 2010 -0700 +++ b/MasterLoop.c Tue Sep 07 18:40:57 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2010 OpenSourceCodeStewardshipFoundation + * Copyright 2010 OpenSourceStewardshipFoundation * * Licensed under BSD */ @@ -98,6 +98,14 @@ masterLoopStartPt: + //============================= MEASUREMENT STUFF ======================== + #ifdef MEAS__TIME_MASTER + //Total Master time includes one coreloop time -- just assume the core + // loop time is same for Master as for AppVPs, even though it will be + // smaller due to high predictability of the jumps. + saveLowTimeStampCountInto( masterPr->startMasterTSCLow ); + #endif + //======================================================================== masterEnv = _VMSMasterEnv; @@ -156,6 +164,13 @@ coreLoopFramePtr = masterPr->coreLoopFramePtr;//need this only coreLoopStackPtr = masterPr->coreLoopStackPtr;//shouldn't need -- safety + #ifdef MEAS__TIME_MASTER + saveLowTimeStampCountInto( masterPr->endMasterTSCLow ); + int diff = masterPr->endMasterTSCLow - masterPr->startMasterTSCLow; + if( diff > 1000000 ) diff = 0; + addToHist( diff, masterEnv->measMasterHist ); + #endif + asm volatile("movl %0, %%eax; \ movl %%esp, (%%eax); \ movl %1, %%eax; \ @@ -167,7 +182,7 @@ movl $0x0, (%%ebx); \ jmp %%eax;" \ /* outputs */ : "=g" (stackPtrAddr), "=g" (framePtrAddr), \ - "=g"(masterLockAddr) \ + "=g"(masterLockAddr) \ /* inputs */ : "g" (jmpPt), "g"(coreLoopStackPtr), "g"(coreLoopFramePtr)\ /* clobber */ : "memory", "%eax", "%ebx", "%ecx", "%edx", "%edi", "%esi" \ );//can probably make clobber list empty -- but safe for now diff -r e69579a0e797 -r 17d20e5cf924 VMS.c --- a/VMS.c Wed Sep 01 08:23:39 2010 -0700 +++ b/VMS.c Tue Sep 07 18:40:57 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2010 OpenSourceCodeStewardshipFoundation + * Copyright 2010 OpenSourceStewardshipFoundation * * Licensed under BSD */ @@ -10,6 +10,7 @@ #include "VMS.h" #include "Queue_impl/BlockingQueue.h" +#include "Histogram/Histogram.h" #define thdAttrs NULL @@ -126,6 +127,17 @@ // in the master, taking from this massive chunk. // initFreeList(); + + //============================= MEASUREMENT STUFF ======================== + #ifdef MEAS__TIME_STAMP_SUSP + _VMSMasterEnv->measSuspHist = makeHistogram( 25, 110, 135 ); + #endif + + #ifdef MEAS__TIME_MASTER + _VMSMasterEnv->measMasterHist = makeHistogram( 25, 500, 800 ); + #endif + //======================================================================== + } /* @@ -293,6 +305,7 @@ newPr->nextInstrPt = fnPtr; newPr->initialData = initialData; newPr->requests = NULL; + newPr->schedSlot = NULL; // newPr->coreLoopStartPt = _VMSMasterEnv->coreLoopStartPt; //fnPtr takes two params -- void *initData & void *animProcr @@ -324,7 +337,7 @@ * next work-unit for that procr. */ void -VMS__suspend_procr( VirtProcr *callingPr ) +VMS__suspend_procr( VirtProcr *animatingPr ) { void *jmpPt, *stackPtrAddr, *framePtrAddr, *coreLoopStackPtr; void *coreLoopFramePtr; @@ -332,21 +345,19 @@ // scheduled again at some future point -- to resume, core loop jumps // to the resume point (below), which causes restore of saved regs and // "return" from this call. - callingPr->nextInstrPt = &&ResumePt; + animatingPr->nextInstrPt = &&ResumePt; //return ownership of the virt procr and sched slot to Master virt pr - callingPr->schedSlot->workIsDone = TRUE; + animatingPr->schedSlot->workIsDone = TRUE; // coreIdx = callingPr->coreAnimatedBy; - stackPtrAddr = &(callingPr->stackPtr); - framePtrAddr = &(callingPr->framePtr); + stackPtrAddr = &(animatingPr->stackPtr); + framePtrAddr = &(animatingPr->framePtr); jmpPt = _VMSMasterEnv->coreLoopStartPt; - coreLoopFramePtr = callingPr->coreLoopFramePtr;//need this only - coreLoopStackPtr = callingPr->coreLoopStackPtr;//shouldn't need -- safety + coreLoopFramePtr = animatingPr->coreLoopFramePtr;//need this only + coreLoopStackPtr = animatingPr->coreLoopStackPtr;//safety - //Eclipse's compilation sequence complains -- so break into two - // separate in-line assembly pieces //Save the virt procr's stack and frame ptrs, asm volatile("movl %0, %%eax; \ movl %%esp, (%%eax); \ @@ -357,6 +368,16 @@ /* clobber */ : "%eax" \ ); + #ifdef MEAS__TIME_STAMP_SUSP + //record time stamp into animating procr: compared to time-stamp + // recorded below, at the resume pt. + //NOTE: doing minimal work here 'cause only a few instrs executed in + // core loop, so only using bottom half of time-stamp -- have to + // externally do sanity check & throw out absurd values due to rollover + + saveLowTimeStampCountInto( animatingPr->preSuspTSCLow ); + #endif + //restore coreloop's frame ptr, then jump back to "start" of core loop //Note, GCC compiles to assembly that saves esp and ebp in the stack // frame -- so have to explicitly do assembly that saves to memory @@ -372,18 +393,23 @@ // assembly, so that stack pointer is correct, before jmp ResumePt: + #ifdef MEAS__TIME_STAMP_SUSP + saveLowTimeStampCountInto( animatingPr->postSuspTSCLow ); + //Take difference between the pre-suspend and post-suspend times + // and do sanity check to see if rollover happened between + int diff = animatingPr->postSuspTSCLow - animatingPr->preSuspTSCLow; + if( diff > 1000000 ) diff = 0; + addToHist( diff, _VMSMasterEnv->measSuspHist ); + + #endif + return; } -/*Not sure yet the form going to put "dissipate" in, so this is the third - * possibility -- the semantic layer can just make a macro that looks like - * a call to its name, then expands to a call to this. - * - *As of June 30, 2010 this looks like the top choice.. - * +/* *This adds a request to dissipate, then suspends the processor so that the * request handler will receive the request. The request handler is what * does the work of freeing memory and removing the processor from the @@ -433,32 +459,8 @@ } - -//TODO: add a semantic-layer supplied "freer" for the semantic-data portion -// of a request -- IE call with both a virt procr and a fn-ptr to request -// freer (or maybe put request freer as a field in virt procr?) -void -VMS__remove_and_free_top_request( VirtProcr *procrWithReq ) - { VMSReqst *req; - - req = procrWithReq->requests; - if( req == NULL ) return; - procrWithReq->requests = procrWithReq->requests->nextReqst; - VMS__free_request( req ); - } - - -//TODO: add a semantic-layer supplied "freer" for the semantic-data portion -// of a request -- IE call with both a virt procr and a fn-ptr to request -// freer (also maybe put sem request freer as a field in virt procr?) -//SSR relies right now on this only freeing VMS layer of request -- the -// semantic portion of request is alloc'd and freed by request handler -void -VMS__free_request( VMSReqst *req ) - { - free( req ); - } - +/*Use this to get first request before starting request handler's loop + */ VMSReqst * VMS__take_top_request_from( VirtProcr *procrWithReq ) { VMSReqst *req; @@ -470,18 +472,36 @@ return req; } +/*A subtle bug due to freeing then accessing "next" after freed caused this + * form of call to be put in -- so call this at end of request handler loop + * that iterates through the requests. + */ VMSReqst * VMS__free_top_and_give_next_request_from( VirtProcr *procrWithReq ) { VMSReqst *req; req = procrWithReq->requests; - if( req == NULL ) return req; + if( req == NULL ) return NULL; procrWithReq->requests = procrWithReq->requests->nextReqst; VMS__free_request( req ); return procrWithReq->requests; } + +//TODO: add a semantic-layer supplied "freer" for the semantic-data portion +// of a request -- IE call with both a virt procr and a fn-ptr to request +// freer (also maybe put sem request freer as a field in virt procr?) +//MeasVMS relies right now on this only freeing VMS layer of request -- the +// semantic portion of request is alloc'd and freed by request handler +void +VMS__free_request( VMSReqst *req ) + { + free( req ); + } + + + inline int VMS__isSemanticReqst( VMSReqst *req ) { @@ -508,7 +528,7 @@ } void -VMS__send_register_new_procr_request(VirtProcr *newPr, VirtProcr *reqstingPr) +VMS__send_req_to_register_new_procr(VirtProcr *newPr, VirtProcr *reqstingPr) { VMSReqst *req; req = malloc( sizeof(VMSReqst) ); @@ -547,7 +567,7 @@ //TODO: implement VMS__malloc system, including "give up ownership" //The dissipate request might still be attached, so remove and free it - VMS__remove_and_free_top_request( animatingPr ); + VMS__free_top_and_give_next_request_from( animatingPr ); //NOTE: initialData was given to the processor, so should either have // been alloc'd with VMS__malloc, or freed by the level above animPr. diff -r e69579a0e797 -r 17d20e5cf924 VMS.h --- a/VMS.h Wed Sep 01 08:23:39 2010 -0700 +++ b/VMS.h Tue Sep 07 18:40:57 2010 -0700 @@ -12,12 +12,22 @@ #include "VMS_primitive_data_types.h" #include "Queue_impl/BlockingQueue.h" +#include "Histogram/Histogram.h" #include //When DEBUG is defined, VMS does sequential exe in the main thread // It still does co-routines and all the mechanisms are the same, it just // has only a single thread and animates VPs one at a time -//#define DEBUG +#define SEQUENTIAL + + //when MEAS__TAKE_SUSP_TSC is defined, causes code to be inserted and + // compiled-in that saves the low part of the time stamp count just before + // suspending a processor and just after resuming that processor. It is + // saved into a field added to VirtProcr. Have to sanity-check for + // rollover of low portion into high portion. +#define MEAS__TIME_STAMP_SUSP +#define MEAS__TIME_MASTER +#define MEAS__NUM_TIMES_TO_RUN 100000 //This value is the number of hardware threads in the shared memory // machine @@ -59,8 +69,6 @@ { void *endThdPt; unsigned int coreNum; -// void *framePtr; -// void *stackPtr; } ThdParams; @@ -109,6 +117,17 @@ VMSReqst *requests; void *semanticData; + + //============================= MEASUREMENT STUFF ======================== + #ifdef MEAS__TIME_STAMP_SUSP + unsigned int preSuspTSCLow; + unsigned int postSuspTSCLow; + #endif + #ifdef MEAS__TIME_MASTER + unsigned int startMasterTSCLow; + unsigned int endMasterTSCLow; + #endif + //======================================================================== }; //VirtProcr @@ -131,6 +150,15 @@ int setupComplete; int masterLock; + + //============================= MEASUREMENT STUFF ======================== + #ifdef MEAS__TIME_STAMP_SUSP + Histogram *measSuspHist; + #endif + #ifdef MEAS__TIME_MASTER + Histogram *measMasterHist; + #endif + //======================================================================== } MasterEnv; @@ -176,7 +204,7 @@ VMS__add_sem_request( void *semReqData, VirtProcr *callingPr ); void -VMS__send_register_new_procr_request( VirtProcr *newPrToRegister, +VMS__send_req_to_register_new_procr( VirtProcr *newPrToRegister, VirtProcr *reqstingPr ); void @@ -234,6 +262,14 @@ /* clobber */ : "%eax", "%edx" \ ); +#define saveLowTimeStampCountInto(low) \ + asm volatile("RDTSC; \ + movl %%eax, %0;" \ + /* outputs */ : "=m" (low) \ + /* inputs */ : \ + /* clobber */ : "%eax", "%edx" \ + ); + inline TSCount getTSCount(); //===================== Debug ==========================