From 461b15f440bd8b6f4609348244fa4c262e08c8c1 Mon Sep 17 00:00:00 2001 From: bdemsky Date: Sun, 22 Feb 2009 08:56:05 +0000 Subject: [PATCH] 1) tweak hash tables 2) optimize range prefetching --- Robust/src/Runtime/DSTM/interface/clookup.c | 9 +- Robust/src/Runtime/DSTM/interface/clookup.h | 5 +- .../src/Runtime/DSTM/interface/dstmserver.c | 2 +- Robust/src/Runtime/DSTM/interface/gCollect.c | 34 +- Robust/src/Runtime/DSTM/interface/mlookup.c | 21 +- Robust/src/Runtime/DSTM/interface/mlookup.h | 5 +- Robust/src/Runtime/DSTM/interface/prefetch.c | 551 ++++++------------ Robust/src/Runtime/DSTM/interface/prefetch.h | 25 +- Robust/src/Runtime/DSTM/interface/prelookup.c | 17 +- Robust/src/Runtime/DSTM/interface/prelookup.h | 5 +- Robust/src/Runtime/DSTM/interface/trans.c | 4 +- 11 files changed, 243 insertions(+), 435 deletions(-) diff --git a/Robust/src/Runtime/DSTM/interface/clookup.c b/Robust/src/Runtime/DSTM/interface/clookup.c index 724086d1..df668cd7 100644 --- a/Robust/src/Runtime/DSTM/interface/clookup.c +++ b/Robust/src/Runtime/DSTM/interface/clookup.c @@ -1,7 +1,7 @@ #include "clookup.h" #define INLINE inline __attribute__((always_inline)) -chashtable_t *chashCreate(unsigned int size, float loadfactor) { +chashtable_t *chashCreate(unsigned int size, double loadfactor) { chashtable_t *ctable; chashlistnode_t *nodes; int i; @@ -19,10 +19,12 @@ chashtable_t *chashCreate(unsigned int size, float loadfactor) { } ctable->table = nodes; + ctable->loadfactor = loadfactor; ctable->size = size; + ctable->threshold=size*loadfactor; ctable->mask = (size << 1)-1; ctable->numelements = 0; // Initial number of elements in the hash - ctable->loadfactor = loadfactor; + return ctable; } @@ -38,7 +40,7 @@ unsigned int chashInsert(chashtable_t *table, unsigned int key, void *val) { int index; chashlistnode_t *ptr, *node; - if(table->numelements > (table->loadfactor * table->size)) { + if(table->numelements > (table->threshold)) { //Resize newsize = table->size << 1; chashResize(table,newsize); @@ -139,6 +141,7 @@ unsigned int chashResize(chashtable_t *table, unsigned int newsize) { table->table = node; //Update the global hashtable upon resize() table->size = newsize; + table->threshold = newsize * table->loadfactor; table->mask = (newsize << 1)-1; for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table diff --git a/Robust/src/Runtime/DSTM/interface/clookup.h b/Robust/src/Runtime/DSTM/interface/clookup.h index fb7a2717..76e8dfde 100644 --- a/Robust/src/Runtime/DSTM/interface/clookup.h +++ b/Robust/src/Runtime/DSTM/interface/clookup.h @@ -18,11 +18,12 @@ typedef struct chashtable { unsigned int size; unsigned int mask; unsigned int numelements; - float loadfactor; + unsigned int threshold; + double loadfactor; } chashtable_t; /* Prototypes for hash*/ -chashtable_t *chashCreate(unsigned int size, float loadfactor); +chashtable_t *chashCreate(unsigned int size, double loadfactor); static unsigned int chashFunction(chashtable_t *table, unsigned int key); unsigned int chashInsert(chashtable_t *table, unsigned int key, void *val); void *chashSearch(chashtable_t *table, unsigned int key); //returns val, NULL if not found diff --git a/Robust/src/Runtime/DSTM/interface/dstmserver.c b/Robust/src/Runtime/DSTM/interface/dstmserver.c index d3f0931f..ff3987d0 100644 --- a/Robust/src/Runtime/DSTM/interface/dstmserver.c +++ b/Robust/src/Runtime/DSTM/interface/dstmserver.c @@ -36,7 +36,7 @@ int dstmInit(void) { pthread_mutexattr_settype(&mainobjstore_mutex_attr, PTHREAD_MUTEX_RECURSIVE_NP); pthread_mutex_init(&mainobjstore_mutex, &mainobjstore_mutex_attr); pthread_mutex_init(&lockObjHeader,NULL); - if (mhashCreate(HASH_SIZE, LOADFACTOR)) + if (mhashCreate(MHASH_SIZE, MLOADFACTOR)) return 1; //failure if (lhashCreate(HASH_SIZE, LOADFACTOR)) diff --git a/Robust/src/Runtime/DSTM/interface/gCollect.c b/Robust/src/Runtime/DSTM/interface/gCollect.c index 1707b230..37cd1503 100644 --- a/Robust/src/Runtime/DSTM/interface/gCollect.c +++ b/Robust/src/Runtime/DSTM/interface/gCollect.c @@ -68,21 +68,23 @@ void *prefetchobjstrAlloc(unsigned int size) { pNodeInfo.os_count--; //need to flush cache clearBlock(tofree); + if (pNodeInfo.newstale==NULL) { + //first store + pNodeInfo.newstale=pNodeInfo.oldstale=tofree; + tofree->prev=NULL; + pNodeInfo.stale_count++; + } else { + //just add it to the list + pNodeInfo.newstale->prev=tofree; + pNodeInfo.newstale=tofree; + pNodeInfo.stale_count++; + } if (pNodeInfo.stale_count>STALE_MAXTHRESHOLD) { - //need to toss store + //need to toss a store + tofree=pNodeInfo.oldstale; + pNodeInfo.oldstale=tofree->prev; + pNodeInfo.stale_count--; free(tofree); - } else { - if (pNodeInfo.newstale==NULL) { - //first store - pNodeInfo.newstale=pNodeInfo.oldstale=tofree; - tofree->prev=NULL; - pNodeInfo.stale_count++; - } else { - //just add it to the list - pNodeInfo.newstale->prev=tofree; - pNodeInfo.newstale=tofree; - pNodeInfo.stale_count++; - } } } @@ -106,8 +108,12 @@ void clearBlock(objstr_t *block) { for(; next != NULL; curr=next, next = next->next) { unsigned int val=(unsigned int)next->val; if ((val>=tmpbegin)&(valnext=next->next; + prehashlistnode_t *tmp=curr->next=next->next; free(next); + next=tmp; + //loop condition is broken now...need to check before incrementing + if (next==NULL) + break; } } { diff --git a/Robust/src/Runtime/DSTM/interface/mlookup.c b/Robust/src/Runtime/DSTM/interface/mlookup.c index 4d5c6263..3f32bf0c 100644 --- a/Robust/src/Runtime/DSTM/interface/mlookup.c +++ b/Robust/src/Runtime/DSTM/interface/mlookup.c @@ -13,6 +13,7 @@ unsigned int mhashCreate(unsigned int size, float loadfactor) { mlookup.table = nodes; mlookup.size = size; + mlookup.mask = (size << 1) -1; mlookup.numelements = 0; // Initial number of elements in the hash mlookup.loadfactor = loadfactor; //Initialize the pthread_mutex variable @@ -22,7 +23,7 @@ unsigned int mhashCreate(unsigned int size, float loadfactor) { // Assign to keys to bins inside hash table unsigned int mhashFunction(unsigned int key) { - return( key % (mlookup.size)); + return( key & mlookup.mask) >>1; } // Insert value and key mapping into the hash table @@ -33,7 +34,7 @@ unsigned int mhashInsert(unsigned int key, void *val) { if (mlookup.numelements > (mlookup.loadfactor * mlookup.size)) { //Resize Table - newsize = 2 * mlookup.size + 1; + newsize = mlookup.size << 1; pthread_mutex_lock(&mlookup.locktable); mhashResize(newsize); pthread_mutex_unlock(&mlookup.locktable); @@ -67,19 +68,18 @@ unsigned int mhashInsert(unsigned int key, void *val) { // Return val for a given key in the hash table void *mhashSearch(unsigned int key) { int index; - mhashlistnode_t *ptr, *node; - + mhashlistnode_t *node; pthread_mutex_lock(&mlookup.locktable); - ptr = mlookup.table; // Address of the beginning of hash table - index = mhashFunction(key); - node = &ptr[index]; - while(node != NULL) { + node = &mlookup.table[(key & mlookup.mask)>>1]; + do { if(node->key == key) { + void * tmp=node->val; pthread_mutex_unlock(&mlookup.locktable); - return node->val; + return tmp; } node = node->next; - } + } while (node!=NULL); + pthread_mutex_unlock(&mlookup.locktable); return NULL; } @@ -137,6 +137,7 @@ unsigned int mhashResize(unsigned int newsize) { mlookup.table = node; //Update the global hashtable upon resize() mlookup.size = newsize; + mlookup.mask = (newsize << 1)-1; mlookup.numelements = 0; for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table diff --git a/Robust/src/Runtime/DSTM/interface/mlookup.h b/Robust/src/Runtime/DSTM/interface/mlookup.h index f3360d4a..fd709732 100644 --- a/Robust/src/Runtime/DSTM/interface/mlookup.h +++ b/Robust/src/Runtime/DSTM/interface/mlookup.h @@ -5,8 +5,8 @@ #include #include -#define LOADFACTOR 0.5 -#define HASH_SIZE 100 +#define MLOADFACTOR 0.25 +#define MHASH_SIZE 1024 typedef struct mhashlistnode { unsigned int key; @@ -17,6 +17,7 @@ typedef struct mhashlistnode { typedef struct mhashtable { mhashlistnode_t *table; // points to beginning of hash table unsigned int size; + unsigned int mask; unsigned int numelements; float loadfactor; pthread_mutex_t locktable; diff --git a/Robust/src/Runtime/DSTM/interface/prefetch.c b/Robust/src/Runtime/DSTM/interface/prefetch.c index 9e36671a..c8fec116 100644 --- a/Robust/src/Runtime/DSTM/interface/prefetch.c +++ b/Robust/src/Runtime/DSTM/interface/prefetch.c @@ -9,22 +9,20 @@ extern sockPoolHashTable_t *transPResponseSocketPool; extern pthread_mutex_t prefetchcache_mutex; extern prehashtable_t pflookup; + // Function for new prefetch call void rangePrefetch(unsigned int oid, short numoffset, short *offsets) { /* Allocate memory in prefetch queue and push the block there */ int qnodesize = sizeof(unsigned int) + sizeof(unsigned short) + numoffset * sizeof(short); char *node = (char *) getmemory(qnodesize); - if(node == NULL) return; - int index = 0; ((unsigned int *)node)[0] = oid; index = index + (sizeof(unsigned int)); *((short *)(node+index)) = numoffset; index = index + (sizeof(short)); memcpy(node+index, offsets, numoffset * sizeof(short)); - movehead(qnodesize); } @@ -34,16 +32,16 @@ void *transPrefetchNew() { void *node = gettail(); /* Check tuples if they are found locally */ - perMcPrefetchList_t* pilehead = checkIfLocal(node); + perMcPrefetchList_t* pilehead = processLocal(node); if (pilehead!=NULL) { - // Get sock from shared pool - int sd = getSock2(transPrefetchSockPool, pilehead->mid); /* Send Prefetch Request */ perMcPrefetchList_t *ptr = pilehead; while(ptr != NULL) { - sendRangePrefetchReq(ptr, sd); + // Get sock from shared pool + int sd = getSock2(transPrefetchSockPool, ptr->mid); + sendRangePrefetchReq(ptr, sd, myIpAddr); ptr = ptr->next; } @@ -55,154 +53,151 @@ void *transPrefetchNew() { } } -int getsize(short *ptr, int n) { - int sum = 0, newsum, i; - for (i = n-1; i >= 0; i--) { - newsum = (1 + ptr[i])+((1 + ptr[i])*sum); - sum = newsum; - } - return sum; -} - - -perMcPrefetchList_t *checkIfLocal(char *ptr) { +perMcPrefetchList_t *processLocal(char *ptr) { unsigned int oid = *(GET_OID(ptr)); short numoffset = *(GET_NUM_OFFSETS(ptr)); short *offsetarray = GET_OFFSETS(ptr); - int depth=0, top=0; + int top; unsigned int dfsList[numoffset]; - oidAtDepth_t odep; + int offstop=numoffset-2; /* Initialize */ perMcPrefetchList_t *head = NULL; - odep.oid = 0; - odep.depth = 0; - int i; - for(i = 0; i= 0) { - int retval; - if((retval = getNextOid(offsetarray, dfsList, &top, &depth, &odep, oid)) != 0) { - printf("%s() Error: Getting new oid at %s, %d\n", __func__, __FILE__, __LINE__); - return NULL; + for(top=0;top>=0;) { + oid=getNextOid(header, offsetarray, dfsList, top); + if (oid&1) { + top+=2; + dfsList[top]=oid; + dfsList[top+1]=0; + header=searchObj(oid); + if (header==NULL) { + //forward prefetch + int machinenum = lhashSearch(dfsList[top]); + insertPrefetch(machinenum, dfsList[top], numoffset-top, &offsetarray[top], &head); + } else if (top=0;) { + oid=getNextOid(header, offsetarray, dfsList, top); + if (oid&1) { + top+=2; + dfsList[top]=oid; + dfsList[top+1]=0; + header=searchObj(oid); + if (header==NULL) { + //forward prefetch int machinenum = lhashSearch(dfsList[top]); - insertPrefetch(machinenum, dfsList[top], numoffset-(depth), &offsetarray[depth], &head); - } - //go up the tree - while((dfsList[top+1] == *(offsetarray + depth + 1)) && (depth >= 0)) { - if(top == depth) { - top -= 2; - depth -= 2; - } else { - depth -= 2; - } - } - //return if no more paths to explore - if(top < 0 || depth < 0) { - return head; - } - //If more paths to explore, proceed down the tree - dfsList[top+1]++; - int prev = top - 2; - objheader_t *header; - header = searchObj(dfsList[prev]); - if(header == NULL) { - dfsList[top] = 0; + insertPrefetch(machinenum, dfsList[top], numoffset-top, &offsetarray[top], &head); } else { - //if Array - if(TYPE(header) > NUMCLASSES) { - dfsList[top] = getNextArrayOid(offsetarray, dfsList, &top, &depth); - } else { //linked list - dfsList[top] = getNextPointerOid(offsetarray, dfsList, &top, &depth); - } + sendOidFound(header, oid, sd); + if (top= numoffset) { //reached the end of the path - top -= 2; - depth -= 2; - //go up the tree - while((dfsList[top + 1] == *(offsetarray + depth + 1)) && (depth >= 0)) { - if(top == depth) { - top -= 2; - depth -= 2; - } else - depth -= 2; - } - //return if no more paths to explore - if(top < 0 || depth < 0) { - return head; - } - //If more paths to explore, go down the tree - dfsList[top + 1]++; - int prev = top - 2; - objheader_t * header; - header = searchObj(dfsList[prev]); - if(header == NULL) { - dfsList[top] = 0; - } else { - //if Array - if(TYPE(header) > NUMCLASSES) { - dfsList[top] = getNextArrayOid(offsetarray, dfsList, &top, &depth); - } else { //linked list - dfsList[top] = getNextPointerOid(offsetarray, dfsList, &top, &depth); - } - } - goto labelL1; - } else - continue; + } else if (oid==2) { + //send prefetch first + int objindex=top+2; + int machinenum = lhashSearch(dfsList[objindex]); + insertPrefetch(machinenum, dfsList[objindex], numoffset-top, &offsetarray[top], &head); } - } //end of while + //oid is 0 + //go backwards until we can increment + do { + do { + top-=2; + if (top<0) + return head; + } while(dfsList[top+1] == GET_RANGE(offsetarray[top + 3])); + + header=searchObj(dfsList[top]); + //header shouldn't be null unless the object moves away, but allow + //ourselves the option to just continue on if we lose the object + } while(header!=NULL); + //increment + dfsList[top+1]++; + } return head; } -objheader_t *searchObj(unsigned int oid) { - objheader_t *header = NULL; +INLINE objheader_t *searchObj(unsigned int oid) { + objheader_t *header; if ((header = (objheader_t *)mhashSearch(oid)) != NULL) { return header; - } else if ((header = (objheader_t *) prehashSearch(oid)) != NULL) { - return header; - } else { - ; - } - return NULL; + } else + return prehashSearch(oid); } /* Delete perMcPrefetchList_t and everything it points to */ void proPrefetchQDealloc(perMcPrefetchList_t *node) { - perMcPrefetchList_t *prefetchpile_ptr; - perMcPrefetchList_t *prefetchpile_next_ptr; - objOffsetPile_t *objpile_ptr; - objOffsetPile_t *objpile_next_ptr; - - prefetchpile_ptr = node; - while (prefetchpile_ptr != NULL) { - prefetchpile_next_ptr = prefetchpile_ptr; - while(prefetchpile_ptr->list != NULL) { + while (node != NULL) { + perMcPrefetchList_t * prefetchpile_next_ptr = node; + while(node->list != NULL) { //offsets aren't owned by us, so we don't free them. - objpile_ptr = prefetchpile_ptr->list; - prefetchpile_ptr->list = objpile_ptr->next; + objOffsetPile_t * objpile_ptr = node->list; + node->list = objpile_ptr->next; free(objpile_ptr); } - prefetchpile_ptr = prefetchpile_next_ptr->next; + node = prefetchpile_next_ptr->next; free(prefetchpile_next_ptr); } } @@ -283,7 +278,7 @@ oidloop: } } -void sendRangePrefetchReq(perMcPrefetchList_t *mcpilenode, int sd) { +void sendRangePrefetchReq(perMcPrefetchList_t *mcpilenode, int sd, unsigned int mid) { int len, endpair; char control; objOffsetPile_t *tmp; @@ -302,7 +297,7 @@ void sendRangePrefetchReq(perMcPrefetchList_t *mcpilenode, int sd) { buf+=sizeof(int); *((unsigned int *)buf) = tmp->oid; buf+=sizeof(unsigned int); - *((unsigned int *)buf) = myIpAddr; + *((unsigned int *)buf) = mid; buf += sizeof(unsigned int); memcpy(buf, tmp->offsets, (tmp->numoffset)*sizeof(short)); send_data(sd, oidnoffset, len); @@ -380,11 +375,18 @@ int rangePrefetchReq(int acceptfd) { short offsetsarry[numoffset]; recv_data(acceptfd, offsetsarry, numoffset*sizeof(short)); - int retval; - if((retval = dfsOffsetTree(baseoid, offsetsarry, sd, numoffset)) != 0) { - printf("%s() Error: in dfsOffsetTree() at line %d in %s()\n", - __func__, __LINE__, __FILE__); - return -1; + perMcPrefetchList_t * pilehead=processRemote(baseoid, offsetsarry, sd, numoffset); + + if (pilehead!= NULL) { + perMcPrefetchList_t *ptr = pilehead; + while(ptr != NULL) { + // Get sock from shared pool + int sd = getSock2(transPrefetchSockPool, ptr->mid); + sendRangePrefetchReq(ptr, sd, mid); + ptr = ptr->next; + } + + proPrefetchQDealloc(pilehead); } } @@ -394,244 +396,57 @@ int rangePrefetchReq(int acceptfd) { return 0; } -int dfsOffsetTree(unsigned int baseoid, short * offsetarray, int sd, int numoffset) { - int depth=0, top=0; - unsigned int dfsList[numoffset]; - oidAtDepth_t odep; - /* Initialize */ - perMcPrefetchList_t *head = NULL; - odep.oid = 0; - odep.depth = 0; - int i; - for(i = 0; i= 0) { - int retval; - if((retval = getNextOid(offsetarray, dfsList, &top, &depth, &odep, baseoid)) != 0) { - printf("%s() Error: Getting new oid at %s, %d\n", __func__, __FILE__, __LINE__); - return -1; - } - dfsList[top] = odep.oid; - dfsList[top+1] = 0; -labelL1: - ; - objheader_t *objhead = searchObj(dfsList[top]); - if(objhead == NULL) { //null oid or oid not found - int retval; - if((retval = sendOidNotFound(dfsList[top], sd)) != 0) { - printf("%s() Error in sendOidNotFound() at line %d in %s()\n", __func__, __LINE__, __FILE__); - return -1; - } - //If not found forward request - forwardRequest(dfsList, &top, &depth, &numoffset, offsetarray); - - //go up the tree - while((dfsList[top+1] == *(offsetarray + depth + 1)) && (depth >= 0)) { - if(top == depth) { - top -= 2; - depth -= 2; - } else { - depth -= 2; - } - } - //return if no more paths to explore - if(top < 0 || depth < 0) { +unsigned int getNextOid(objheader_t * header, short * offsetarray, unsigned int *dfsList, int top) { + int startindex= offsetarray[top+2]; + int currcount = dfsList[top+1]; + int range = GET_RANGE(offsetarray[top + 3]); + + if(TYPE(header) > NUMCLASSES) { + //Array case + struct ArrayObject *ao = (struct ArrayObject *) (((char *)header) + sizeof(objheader_t)); + int stride = GET_STRIDE(offsetarray[top + 3])+1; + int length = ao->___length___; + int currindex; + //Check direction of stride + if(GET_STRIDEINC(offsetarray[top + 3])) { + //Negative + currindex=startindex-stride*currcount; + if (currindex<0) return 0; - } - //If more paths to explore, proceed down the tree - dfsList[top+1]++; - int prev = top - 2; - objheader_t *header; - header = searchObj(dfsList[prev]); - if(header == NULL) { - dfsList[top] = 0; - } else { - //if Array - if(TYPE(header) > NUMCLASSES) { - dfsList[top] = getNextArrayOid(offsetarray, dfsList, &top, &depth); - } else { //linked list - dfsList[top] = getNextPointerOid(offsetarray, dfsList, &top, &depth); - } - goto labelL1; - } - } else { // increment and go down the tree - //Send Object id found - if((retval = sendOidFound(OID(objhead), sd)) != 0) { - printf("%s() Error in sendOidFound() at line %d in %s()\n", __func__, __LINE__, __FILE__); - return -1; - } - //Increment top - top += 2; - depth += 2; - if(depth >= numoffset) { //reached the end of the path - top -= 2; - depth -= 2; - //go up the tree - while((dfsList[top + 1] == *(offsetarray + depth + 1)) && (depth >= 0)) { - if(top == depth) { - top -= 2; - depth -= 2; - } else - depth -= 2; - } - //return if no more paths to explore - if(top < 0 || depth < 0) { - return 0; - } - //If more paths to explore, go down the tree - dfsList[top + 1]++; - int prev = top - 2; - objheader_t * header; - header = searchObj(dfsList[prev]); - if(header == NULL) { - dfsList[top] = 0; - } else { - //if Array - if(TYPE(header) > NUMCLASSES) { - dfsList[top] = getNextArrayOid(offsetarray, dfsList, &top, &depth); - } else { //linked list - dfsList[top] = getNextPointerOid(offsetarray, dfsList, &top, &depth); - } - } - goto labelL1; - } else - continue; - } - } //end of while - return 0; -} -int getNextOid(short * offsetarray, unsigned int *dfsList, int *top, int *depth, oidAtDepth_t *odep, unsigned int baseoid) { - if(*top == 0) { - odep->oid = baseoid; - odep->depth = 0; - } else { - int prev = (*top) - 2; - unsigned int oid = *(dfsList+prev); - objheader_t * header = searchObj(oid); - if(header == NULL) { - odep->oid = 0; - odep->depth = 0; - return 0; - } else { - int range = GET_RANGE(*(offsetarray+(*depth) + 1)); - short stride = GET_STRIDE(*(offsetarray+(*depth) + 1)); - stride++; //Note bit pattern 000 => stride = 1 etc - //if Array - if(TYPE(header) > NUMCLASSES) { - int elementsize = classsize[TYPE(header)]; - struct ArrayObject *ao = (struct ArrayObject *) (((char *)header) + sizeof(objheader_t)); - int length = ao->___length___; - //check is stride is +ve or -ve - int sign; - if(GET_STRIDEINC(*(offsetarray+ (*depth) + 1))) { - sign = -1; - } else { - sign = 1; - } - int startelement = *(offsetarray + (*depth)); - if(startelement < 0 || startelement >=length) { - printf("%s() Error: Offset out of range at %d\n", __func__, __LINE__); - odep->oid = 0; - odep->depth = 0; - return 0; - } - int index = *(dfsList+(*top)+1); - odep->oid = *((unsigned int *)(((char *)ao) + sizeof(struct ArrayObject) \ - + (elementsize * (startelement + (sign*stride*index))))); - odep->depth = *(depth); - } else { //linked list - int dep; - int startelement; - if(range > 0) { //go to the next offset - startelement = *((int *)(offsetarray + (*depth) + 2)); - *depth = *depth + 2; - } else if(range == 0) { - startelement = *((int *)(offsetarray + (*depth))); - } else { //range < 0 - odep->oid = 0; - odep->depth = 0; + //Also have to check whether we will eventually index into array + if (currindex>=length) { + //Skip to the point that we will index into array + int delta=(currindex-length-1)/stride+1; //-1, +1 is to make sure that it rounds up + if ((delta+currcount)>range) return 0; - } - odep->oid = *((unsigned int *)(((char *)header) + sizeof(objheader_t) + startelement)); - odep->depth = *depth; + currindex-=delta*stride; } - } - } - return 0; -} - -unsigned int getNextArrayOid(short *offsetarray, unsigned int *dfsList, int *top, int* depth) { - int prev = (*top) - 2; - unsigned int oid = *(dfsList + prev); - if(oid == 0) { //null oid - return oid; - } - objheader_t *header = searchObj(oid); - if(header == NULL) { - return 0; - } else { - short stride = GET_STRIDE(*(offsetarray+(*depth) + 1)); - stride++; //Note bit pattern 000 => stride = 1 etc - //check is stride is +ve or -ve - int sign; - if(GET_STRIDEINC(*(offsetarray+ (*depth) + 1))) { - sign = -1; } else { - sign = 1; + //Going positive, compute current index + currindex=startindex+stride*currcount; + if(currindex >= length) + return 0; } + int elementsize = classsize[TYPE(header)]; - struct ArrayObject *ao = (struct ArrayObject *) (((char *)header) + sizeof(objheader_t)); - int length = ao->___length___; - int startelement = *(offsetarray + (*depth)); - if(startelement < 0 || startelement >=length) { - printf("%s() Error: Offset out of range at %d\n", __func__, __LINE__); - return 0; + return *((unsigned int *)(((char *)ao) + sizeof(struct ArrayObject) + elementsize*currindex)); + } else { + //handle fields + + if(currcount!=0 & range != 0) { + //go to the next offset + header=searchObj(dfsList[top]); + if (header==NULL) + return 2; } - int index = *(dfsList + *top + 1); - oid = *((unsigned int *)(((char *)ao) + sizeof(struct ArrayObject) \ - + (elementsize * (startelement + (sign*stride*index))))); - } - return oid; -} -unsigned int getNextPointerOid(short *offsetarray, unsigned int *dfsList, int *top, int* depth) { - int prev; - if(*(dfsList + *top + 1) > 1) { //tells which offset to calculate the oid from - //(if range > 1 then use available oid to compute next oid else go to previous oid) - prev = *top; - } else { - prev = *top - 2; - } - unsigned int oid = *(dfsList + prev); - if(oid == 0) { //null oid - return oid; - } - objheader_t *header = searchObj(oid); - if(header == NULL) { - return 0; - } else { - int startelement = *(offsetarray + *depth); - oid = *((unsigned int *)(((char *)header) + sizeof(objheader_t) + startelement)); - //TODO add optimization for checking if this oid has already not been found + return *((unsigned int *)(((char *)header) + sizeof(objheader_t) + startindex)); } - return oid; } -int sendOidFound(unsigned int oid, int sd) { - objheader_t *header; - if((header = (objheader_t *) mhashSearch(oid)) != NULL) { - ; - } else if((header = (objheader_t *) prehashSearch(oid))!=NULL) { - ; - } else { - return 0; - } - +int sendOidFound(objheader_t * header, unsigned int oid, int sd) { int incr = 0; int objsize; GETSIZE(objsize, header); @@ -660,19 +475,3 @@ int sendOidNotFound(unsigned int oid, int sd) { sendPrefetchResponse(sd, &control, sendbuffer, &size); return 0; } - -void forwardRequest(unsigned int * dfsList, int *top, int *depth, int *numoffset, short * offsetarray) { - perMcPrefetchList_t *head = NULL; - unsigned int machinenum = lhashSearch(*(dfsList + *top)); - insertPrefetch(machinenum, *(dfsList + *top), (*numoffset)-(*depth), &offsetarray[*depth], &head); - - if(head!=NULL) { - // Get sock from shared pool - int sd = getSock2(transPrefetchSockPool, machinenum); - /* Send Prefetch Request */ - sendRangePrefetchReq(head, sd); - /* Deallocated pilehead */ - proPrefetchQDealloc(head); - } - return; -} diff --git a/Robust/src/Runtime/DSTM/interface/prefetch.h b/Robust/src/Runtime/DSTM/interface/prefetch.h index 1ec456ed..867bde8f 100644 --- a/Robust/src/Runtime/DSTM/interface/prefetch.h +++ b/Robust/src/Runtime/DSTM/interface/prefetch.h @@ -10,6 +10,9 @@ #define GET_NUM_OFFSETS(x) ((short *) (x + sizeof(unsigned int))) #define GET_OFFSETS(x) ((short *) (x + sizeof(unsigned int) + sizeof(short))) +#define INLINE inline __attribute__((always_inline)) + + /****** Global structure **********/ typedef struct objOffsetPile { unsigned int oid; @@ -45,29 +48,21 @@ void proPrefetchQDealloc(perMcPrefetchList_t *); /******** Process Queue Element functions ***********/ void rangePrefetch(unsigned int, short, short *); void *transPrefetchNew(); -perMcPrefetchList_t* checkIfLocal(char *ptr); -int lookForObjs(int*, short *, int *, int *, int *, int *); +perMcPrefetchList_t* processLocal(char *ptr); +perMcPrefetchList_t *processRemote(unsigned int oid, short * offsetarray, int sd, short numoffset); void insertPrefetch(int, unsigned int, short, short*, perMcPrefetchList_t **); /******** Sending and Receiving Prefetches *******/ -void sendRangePrefetchReq(perMcPrefetchList_t *, int sd); +void sendRangePrefetchReq(perMcPrefetchList_t *, int sd, unsigned int mid); int rangePrefetchReq(int acceptfd); int processOidFound(objheader_t *, short *, int, int, int); -int processArrayOids(short *, objheader_t *, int *, int); -int findOidinStride(short *, struct ArrayObject *, int, int, int, int, int, int); -int processLinkedListOids(short *, objheader_t *, int *, int); int getRangePrefetchResponse(int sd); -objheader_t *searchObj(unsigned int); -void forwardRequest(unsigned int *, int*, int*, int*, short*); +INLINE objheader_t *searchObj(unsigned int); + /*********** Functions for computation at the participant end **********/ -int getNextOid(short *, unsigned int*, int*, int*, oidAtDepth_t *, unsigned int); -unsigned int getNextArrayOid(short *, unsigned int *, int *, int*); -unsigned int getNextPointerOid(short *, unsigned int *, int *, int*); -int sendOidFound(unsigned int, int); +unsigned int getNextOid(objheader_t * header, short * offsetarray, unsigned int *dfsList, int top); +int sendOidFound(objheader_t *, unsigned int, int); int sendOidNotFound(unsigned int oid, int sd); -/************* Internal functions *******************/ -int getsize(short *ptr, int n); - #endif diff --git a/Robust/src/Runtime/DSTM/interface/prelookup.c b/Robust/src/Runtime/DSTM/interface/prelookup.c index 0e3c17c9..aee97260 100644 --- a/Robust/src/Runtime/DSTM/interface/prelookup.c +++ b/Robust/src/Runtime/DSTM/interface/prelookup.c @@ -18,6 +18,7 @@ unsigned int prehashCreate(unsigned int size, float loadfactor) { } pflookup.table = nodes; pflookup.size = size; + pflookup.mask = (size << 1) -1; pflookup.numelements = 0; // Initial number of elements in the hash pflookup.loadfactor = loadfactor; @@ -36,7 +37,7 @@ unsigned int prehashCreate(unsigned int size, float loadfactor) { //Assign keys to bins inside hash table unsigned int prehashFunction(unsigned int key) { - return ( key % (pflookup.size)); + return ( key & pflookup.mask) >> 1; } //Store oids and their pointers into hash @@ -47,7 +48,7 @@ unsigned int prehashInsert(unsigned int key, void *val) { if(pflookup.numelements > (pflookup.loadfactor * pflookup.size)) { //Resize - newsize = 2 * pflookup.size + 1; + newsize = pflookup.size << 1; pthread_mutex_lock(&pflookup.lock); prehashResize(newsize); pthread_mutex_unlock(&pflookup.lock); @@ -82,16 +83,15 @@ void *prehashSearch(unsigned int key) { prehashlistnode_t *ptr, *node; pthread_mutex_lock(&pflookup.lock); - ptr = pflookup.table; - index = prehashFunction(key); - node = &ptr[index]; - while(node != NULL) { + node = & pflookup.table[(key & pflookup.mask)>>1]; + do { if(node->key == key) { + void * tmp=node->val; pthread_mutex_unlock(&pflookup.lock); - return node->val; + return tmp; } node = node->next; - } + } while (node!=NULL); pthread_mutex_unlock(&pflookup.lock); return NULL; } @@ -148,6 +148,7 @@ unsigned int prehashResize(unsigned int newsize) { pflookup.table = node; //Update the global hashtable upon resize() pflookup.size = newsize; + pflookup.mask = (newsize << 1) -1; pflookup.numelements = 0; for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table diff --git a/Robust/src/Runtime/DSTM/interface/prelookup.h b/Robust/src/Runtime/DSTM/interface/prelookup.h index 023e53cc..30b21fec 100644 --- a/Robust/src/Runtime/DSTM/interface/prelookup.h +++ b/Robust/src/Runtime/DSTM/interface/prelookup.h @@ -6,8 +6,8 @@ #include #include "dstm.h" -#define LOADFACTOR 0.5 -#define HASH_SIZE 100 +#define PLOADFACTOR 0.25 +#define PHASH_SIZE 1024 typedef struct prehashlistnode { unsigned int key; @@ -20,6 +20,7 @@ struct objstr; typedef struct prehashtable { prehashlistnode_t *table; // points to beginning of hash table unsigned int size; + unsigned int mask; unsigned int numelements; float loadfactor; pthread_mutex_t lock; diff --git a/Robust/src/Runtime/DSTM/interface/trans.c b/Robust/src/Runtime/DSTM/interface/trans.c index 7c1b2fc5..69c71c72 100644 --- a/Robust/src/Runtime/DSTM/interface/trans.c +++ b/Robust/src/Runtime/DSTM/interface/trans.c @@ -272,7 +272,7 @@ void transInit() { pthread_mutex_init(&atomicObjLock, NULL); #ifdef CACHE //Create prefetch cache lookup table - if(prehashCreate(HASH_SIZE, LOADFACTOR)) { + if(prehashCreate(PHASH_SIZE, PLOADFACTOR)) { printf("ERROR\n"); return; //Failure } @@ -1309,11 +1309,11 @@ void *transPrefetch(void *t) { if (pilehead!=NULL) { // Get sock from shared pool - int sd = getSock2(transPrefetchSockPool, pilehead->mid); /* Send Prefetch Request */ prefetchpile_t *ptr = pilehead; while(ptr != NULL) { + int sd = getSock2(transPrefetchSockPool, ptr->mid); sendPrefetchReq(ptr, sd); ptr = ptr->next; } -- 2.34.1