From: adash Date: Sat, 15 Dec 2007 01:06:00 +0000 (+0000) Subject: In prefetch analysis: X-Git-Tag: preEdgeChange~337 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=915d679a6d3c36a1eb62e8523e55f5452c2178ce;p=IRC.git In prefetch analysis: a) deleted the shorter subset prefetch pairs from the prefetch set for a given FlatNode b) deleted prefetch pairs generating NULL pointer in C code In Runtime: Added support for prefetching arrays --- diff --git a/Robust/src/Analysis/Prefetch/IndexDescriptor.java b/Robust/src/Analysis/Prefetch/IndexDescriptor.java index 97a9158b..78d3c316 100644 --- a/Robust/src/Analysis/Prefetch/IndexDescriptor.java +++ b/Robust/src/Analysis/Prefetch/IndexDescriptor.java @@ -91,7 +91,7 @@ public class IndexDescriptor extends Descriptor { public boolean equals(Object o) { if(o instanceof IndexDescriptor) { IndexDescriptor idesc = (IndexDescriptor) o; - if(!offset.equals(idesc.offset)) { + if(!(offset.equals(idesc.offset))) { return false; } if(tddesc == null && idesc.tddesc == null) { diff --git a/Robust/src/Analysis/Prefetch/PrefetchAnalysis.java b/Robust/src/Analysis/Prefetch/PrefetchAnalysis.java index 94210be7..4b649a8e 100644 --- a/Robust/src/Analysis/Prefetch/PrefetchAnalysis.java +++ b/Robust/src/Analysis/Prefetch/PrefetchAnalysis.java @@ -115,7 +115,6 @@ public class PrefetchAnalysis { if(newprefetchset.size() > 0) { addFlatPrefetchNode(newprefetchset); } - //printMethod(fm); } } @@ -508,7 +507,7 @@ public class PrefetchAnalysis { childpp = (PrefetchPair) ecld.nextElement(); if(childpp.base == currfsfn.getDst()) { int size = childpp.desc.size(); - if(size >=2) { + if(size >=2) { /*e.g. x.f = g (with child prefetches x.f.g, x.f[0].j) */ if((childpp.getDescAt(0) instanceof FieldDescriptor) && (childpp.getDescAt(0) == currfsfn.getField())) { ArrayList newdesc = new ArrayList(); for(int i = 0;i<(childpp.desc.size()-1); i++) { @@ -532,7 +531,7 @@ public class PrefetchAnalysis { child_prefetch_set_copy.remove(newpp); } } - } else if(size==1) { + } else if(size==1) { /* e.g x.f = g (with child prefetch x.f) */ if((childpp.getDescAt(0) instanceof FieldDescriptor) && (childpp.getDescAt(0) == currfsfn.getField())) { child_prefetch_set_copy.remove(childpp); } @@ -569,7 +568,7 @@ public class PrefetchAnalysis { } } - /** This function processes the prefetch set of a FlatSeElementNode + /** This function processes the prefetch set of a FlatSetElementNode * It generates a new prefetch set after comparision with its children * It compares the old prefetch set with this new prefetch set and enqueues the parents * of the current node if change occurs and then updates the global flatnode hash table @@ -589,8 +588,9 @@ public class PrefetchAnalysis { int sizedesc = childpp.desc.size(); if((childpp.getDescAt(0) instanceof IndexDescriptor)) { int sizetempdesc = ((IndexDescriptor)(childpp.getDescAt(0))).tddesc.size(); - if(sizetempdesc == 1) { + if(sizetempdesc == 1) { if((((IndexDescriptor)childpp.getDescAt(0)).tddesc.get(0) == currfsen.getIndex()) && (sizedesc>=2)) { + /* For e.g. a[i] = g with child prefetch set a[i].r or a[i].r.f */ ArrayList newdesc = new ArrayList(); for(int i = 0;i<(childpp.desc.size()-1); i++) { newdesc.add(i,childpp.desc.get(i+1)); @@ -612,6 +612,7 @@ public class PrefetchAnalysis { child_prefetch_set_copy.remove(newpp); } } else if((((IndexDescriptor)childpp.getDescAt(0)).tddesc.get(0) == currfsen.getIndex()) && (sizedesc==1)) + /* For e.g. a[i] = g with child prefetch set a[i] */ child_prefetch_set_copy.remove(childpp); } else { continue; @@ -665,7 +666,7 @@ public class PrefetchAnalysis { childpp = (PrefetchPair) ecld.nextElement(); PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone(); - /* For cases like x=y followed by childnode t=x[i].z or t=x.g*/ + /* For cases like x=y with child prefetch set x[i].z,x.g*/ if(childpp.base == currfopn.getDest()) { ArrayList newdesc = new ArrayList(); newdesc.addAll(childpp.desc); @@ -685,7 +686,7 @@ public class PrefetchAnalysis { } child_prefetch_set_copy.remove(newpp); } - /* For cases like x=y followed by t = r[i].x or t =r[x].p or t = r[p+x].q*/ + /* For cases like x=y with child prefetch set r[i].x, r[x].p, r[p+x].q*/ } else if(isTempDescFound(copyofchildpp, currfopn.getDest())) { ArrayList newdesc = new ArrayList(); newdesc.addAll((ArrayList)getNewDesc(copyofchildpp, currfopn.getDest(), currfopn.getLeft())); @@ -709,7 +710,7 @@ public class PrefetchAnalysis { continue; } } - //case i = i+z followed by a[i].x + //case i = i+z with child prefetch set a[i].x } else if(currfopn.getRight()!=null && (currfopn.getOp().getOp() == Operation.ADD)) { ecld = child_prefetch_set_copy.keys(); while (ecld.hasMoreElements()) { @@ -771,7 +772,7 @@ public class PrefetchAnalysis { } /** This function processes a FlatLiteralNode where cases such as - * for cases like i = 0 followed by t = a[i].r or t = a[j+i].r or t = a[j].b[i].r + * for e.g. i = 0 with child prefetch sets a[i].r, a[j+i].r or a[j].b[i].r * are handled */ private void processFlatLiteralNode(FlatNode curr, Hashtable child_prefetch_set_copy, Hashtable parentpmap) { @@ -787,7 +788,6 @@ public class PrefetchAnalysis { while (ecld.hasMoreElements()) { childpp = (PrefetchPair) ecld.nextElement(); PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone(); - /* For cases like i = 0 followed by t = a[i].r or t = a[j+i].r or t = a[j].b[i].r*/ if(isTempDescFound(copyofchildpp,currfln.getDst())) { ArrayList copychilddesc = (ArrayList) copyofchildpp.getDesc(); int sizetempdesc = copychilddesc.size(); @@ -889,8 +889,8 @@ public class PrefetchAnalysis { } /** This Function processes the FlatCalls - * It currently drops the propagation of those prefetchpairs that are passed as - * arguments in the FlatCall + * It currently drops the propagation of those prefetchpairs whose base is + * same as the destination of the FlatCall */ private void processFlatCall(FlatNode curr, Hashtable child_prefetch_set_copy, Hashtable parentpmap) { @@ -1226,13 +1226,83 @@ public class PrefetchAnalysis { } } + delSubsetPPairs(); + + /* Start with a top down sorted order of nodes */ while(!newvisited.isEmpty()) { applyPrefetchInsertRules((FlatNode) newvisited.getFirst()); newvisited.remove(0); } } + private void delSubsetPPairs() { + Enumeration e = prefetch_hash.keys(); + while(e.hasMoreElements()) { + FlatNode fn = (FlatNode) e.nextElement(); + Hashtable ppairs = prefetch_hash.get(fn); + Enumeration epp = ((Hashtable)(prefetch_hash.get(fn))).keys(); + Vector pplist = new Vector(); + Vector pplength = new Vector(); + Vector ppisMod = new Vector(); + while(epp.hasMoreElements()) { + PrefetchPair pp = (PrefetchPair) epp.nextElement(); + pplist.add(pp); + int length = pp.desc.size()+ 1; + pplength.add(length); + ppisMod.add(0); + } + int numpp = ((Hashtable)(prefetch_hash.get(fn))).size(); + for (int i = 0; i < numpp; i++) { + for (int j = i+1; j < numpp; j++) { + boolean ret; + int x = ((Integer) (pplength.get(i))).intValue(); + if (((Integer) (pplength.get(i))).intValue() < ((Integer)( pplength.get(j))).intValue()) { + ret = isSubSet(pplist.get(i), pplist.get(j)); + if (ret) { + ppisMod.set(i, 1); + } + } else { + ret = isSubSet(pplist.get(j), pplist.get(i)); + if (ret) { + ppisMod.set(j, 1); + } + } + } + } + for (int i = 0; i < numpp; i++) { + if (((Integer)(ppisMod.get(i))).intValue() == 1) { + PrefetchPair pp = (PrefetchPair) pplist.get(i); + ppairs.remove(pp); + } + } + } + } + private boolean isSubSet(PrefetchPair shrt, PrefetchPair lng) { + if (shrt.base != lng.base) { + return false; + } + for (int j = 0; j < shrt.desc.size(); j++) { + if(shrt.getDescAt(j) instanceof IndexDescriptor) { + IndexDescriptor shrtid = (IndexDescriptor) shrt.getDescAt(j); + if(lng.getDescAt(j) instanceof IndexDescriptor){ + IndexDescriptor lngid = (IndexDescriptor) lng.getDescAt(j); + if(shrtid.equals(lngid)) { + continue; + } else { + return false; + } + } else { + return false; + } + } else { + if ((Descriptor)shrt.getDescAt(j) != (Descriptor)lng.getDescAt(j)){ + return false; + } + } + } + return true; + } /**This function compares all the prefetch pairs in a Prefetch set hashtable and * returns: true if something has changed in the new Prefetch set else @@ -1385,11 +1455,11 @@ public class PrefetchAnalysis { } } - private void addFlatPrefetchNode(Hashtable> newprefetchset) { int i; Enumeration e = null; e = newprefetchset.keys(); + boolean isFNPresent = false; /* Detects presence of FlatNew node */ /* This modifies the graph */ while(e.hasMoreElements()) { FlatNode fn = (FlatNode) e.nextElement(); @@ -1397,21 +1467,31 @@ public class PrefetchAnalysis { for(i = 0; i< newprefetchset.get(fn).size(); i++) { fpn.insAllpp((HashSet)newprefetchset.get(fn)); } - //System.out.println("The HashSet of prefetch pairs are "+ fpn.getPrefetchPairs()); if(fn.kind() == FKind.FlatMethod) { FlatNode nn = fn.getNext(0); fn.setNext(0, fpn); fpn.addNext(nn); } else { - while(fn.numPrev() > 0) { - FlatNode nn = fn.getPrev(0); - for(int j = 0; j 0) { + FlatNode nn = fn.getPrev(0); + for(int j = 0; j NUMCLASSES) { + isArray = 1; + } + if(isArray == 1) { + int elementsize = classsize[TYPE(header)]; + objoid = *((unsigned int *)(((char *)header) + sizeof(objheader_t) + sizeof(struct ArrayObject) + (elementsize*offset[i]))); + } else { + objoid = *((unsigned int *)(((char *)header) + sizeof(objheader_t) + offset[i])); + } + if((header = mhashSearch(objoid)) == NULL) { + /* Obj not found, send oid */ + *(buffer + index) = OBJECT_NOT_FOUND; + index += sizeof(char); + memcpy(buffer+index, &oid, sizeof(unsigned int)); + index += sizeof(unsigned int); + break; + } else {/* Obj Found */ + /* send the oid, it's size, it's header and data */ + GETSIZE(size, header); + size+=sizeof(objheader_t); + *(buffer + index) = OBJECT_FOUND; + index += sizeof(char); + memcpy(buffer+index, &oid, sizeof(unsigned int)); + index += sizeof(unsigned int); + memcpy(buffer+index, &size, sizeof(int)); + index += sizeof(int); + memcpy(buffer+index, header, size); + index += size; + isArray = 0; + continue; + } } } /* Check for overflow in the buffer */ diff --git a/Robust/src/Runtime/DSTM/interface/trans.c b/Robust/src/Runtime/DSTM/interface/trans.c index 65e48e52..c65127f5 100644 --- a/Robust/src/Runtime/DSTM/interface/trans.c +++ b/Robust/src/Runtime/DSTM/interface/trans.c @@ -315,7 +315,7 @@ objheader_t *transRead(transrecord_t *record, unsigned int oid) { return objcopy; #endif } else if (rc == ETIMEDOUT) { -// printf("Wait timed out\n"); + printf("Wait timed out\n"); pthread_mutex_unlock(&pflookup.lock); break; } @@ -1127,26 +1127,17 @@ void checkPrefetchTuples(prefetchqelem_t *node) { if(i == 0) { k = 0; - index = endoffsets[j -1]; - for(count = 0; count < slength; count ++) { - if (arryfields[k] != arryfields[index]) { - break; - } - index++; - k++; - } } else { k = endoffsets[i-1]; - index = endoffsets[j-1]; - for(count = 0; count < slength; count++) { - if(arryfields[k] != arryfields[index]) { - break; - } - index++; - k++; - } } - + index = endoffsets[j -1]; + for(count = 0; count < slength; count ++) { + if (arryfields[k] != arryfields[index]) { + break; + } + index++; + k++; + } if(slength == count) { oid[sindex] = 0; } @@ -1154,66 +1145,6 @@ void checkPrefetchTuples(prefetchqelem_t *node) { } } } - -void checkPreCache(prefetchqelem_t *node, int *numoffset, int counter, int loopcount, unsigned int objoid, int index, int iter, int oidnfound) { - char *ptr, *tmp; - int ntuples, i, k, flag; - unsigned int * oid; - short *endoffsets, *arryfields; - objheader_t *header; - - ptr = (char *) node; - ntuples = *(GET_NTUPLES(ptr)); - oid = GET_PTR_OID(ptr); - endoffsets = GET_PTR_EOFF(ptr, ntuples); - arryfields = GET_PTR_ARRYFLD(ptr, ntuples); - - if(oidnfound == 1) { - if((header = (objheader_t *) prehashSearch(objoid)) == NULL) { - return; - } else { //Found in Prefetch Cache - //TODO Decide if object is too old, if old remove from cache - tmp = (char *) header; - /* Check if any of the offset oid is available in the Prefetch cache */ - for(i = counter; i < loopcount; i++) { - objoid = *(tmp + sizeof(objheader_t) + arryfields[counter]); - if((header = (objheader_t *)prehashSearch(objoid)) != NULL) { - flag = 0; - } else { - flag = 1; - break; - } - } - } - } else { - for(i = counter; i NUMCLASSES) { + isArray = 1; + } + if(isArray == 1) { + int elementsize = classsize[TYPE(objheader)]; + struct ArrayObject *ao = (struct ArrayObject *) (tmp + sizeof(objheader_t)); + objoid = *((unsigned int *)(tmp + sizeof(objheader_t) + sizeof(struct ArrayObject) + (elementsize*arryfields[arryfieldindex]))); + } else { + objoid = *(tmp + sizeof(objheader_t) + arryfields[arryfieldindex]); + } + //Update numoffset array + numoffset[i] = numoffset[i] - 1; + //Update oid array oid[i] = objoid; - numoffset[i] = numoffset[i] - (j+1); - for(k = 0; k < numoffset[i]; k++) - arryfields[endoffsets[j]+ k] = arryfields[endoffsets[j]+k+1]; - index++; - /*New offset oid not found */ - if((objheader = (objheader_t*) mhashSearch(objoid)) == NULL) { + //Update endoffset array + endoffsets[0] = val = numoffset[0]; + for(k = 1; k < ntuples; k++) { + val = val + numoffset[k]; + endoffsets[k] = val; + } + //Update arrayfields array + for(k = 0; k < endoffsets[ntuples-1]; k++) { + arryfields[arryfieldindex+k] = arryfields[arryfieldindex+k+1]; + } + if((objheader = (objheader_t*) mhashSearch(oid[i])) == NULL) { flag = 1; - checkPreCache(node, numoffset, j, numoffset[i], objoid, index, i, oidnfound); + checkPreCache(node, numoffset, oid[i], i); break; - } else - flag = 0; + } + tmp = (char *) objheader; + isArray = 0; } - /*If all offset oids are found locally,make the prefetch tuple invalid */ if(flag == 0) { oid[i] = 0; - numoffset[i] = 0; } } else { - oidnfound = 1; /* Look in Prefetch cache */ - checkPreCache(node, numoffset, 0, numoffset[i], oid[i], 0, i, oidnfound); + checkPreCache(node, numoffset, oid[i],i); } } @@ -1318,6 +1278,72 @@ prefetchpile_t *foundLocal(prefetchqelem_t *node) { return head; } +void checkPreCache(prefetchqelem_t *node, int *numoffset, unsigned int objoid, int index) { + char *ptr, *tmp; + int ntuples, i, k, flag=0, isArray =0, arryfieldindex, val; + unsigned int * oid; + short *endoffsets, *arryfields; + objheader_t *header; + + ptr = (char *) node; + ntuples = *(GET_NTUPLES(ptr)); + oid = GET_PTR_OID(ptr); + endoffsets = GET_PTR_EOFF(ptr, ntuples); + arryfields = GET_PTR_ARRYFLD(ptr, ntuples); + + if((header = (objheader_t *) prehashSearch(objoid)) == NULL) { + return; + } else { //Found in Prefetch Cache + //TODO Decide if object is too old, if old remove from cache + tmp = (char *) header; + int loopcount = numoffset[index]; + if(index == 0) + arryfieldindex = 0; + else + arryfieldindex = endoffsets[(index - 1)]; + // Check if any of the offset oid is available in the Prefetch cache + for(i = 0; i < loopcount; i++) { + /* Check for arrays */ + if(TYPE(header) > NUMCLASSES) { + isArray = 1; + } + if(isArray == 1) { + int elementsize = classsize[TYPE(header)]; + objoid = *((unsigned int *)(tmp + sizeof(objheader_t) + sizeof(struct ArrayObject) + (elementsize*arryfields[arryfieldindex]))); + } else { + objoid = *(tmp + sizeof(objheader_t) + arryfields[arryfieldindex]); + } + //Update numoffset array + numoffset[index] = numoffset[index] - 1; + //Update oid array + oid[index] = objoid; + //Update endoffset array + endoffsets[0] = val = numoffset[0]; + for(k = 1; k < ntuples; k++) { + val = val + numoffset[k]; + endoffsets[k] = val; + } + //Update arrayfields array + for(k = 0; k < endoffsets[ntuples-1]; k++) { + arryfields[arryfieldindex+k] = arryfields[arryfieldindex+k+1]; + } + if((header = (objheader_t *)prehashSearch(oid[index])) != NULL) { + tmp = (char *) header; + isArray = 0; + } else { + flag = 1; + break; + } + } + } + //Found in the prefetch cache + if(flag == 0 && (numoffset[index] == 0)) { + oid[index] = 0; + } +} + + + /* This function is called by the thread calling transPrefetch */ void *transPrefetch(void *t) { prefetchqelem_t *qnode; @@ -1748,4 +1774,3 @@ int findHost(unsigned int hostIp) //not found return -1; } -