int FileBufferMgr::bulkInsert(const vector<CacheInsert_t> &ops) { uint32_t i; int32_t pi; int ret = 0; mutex::scoped_lock lk(fWLock); for (i = 0; i < ops.size(); i++) { const CacheInsert_t &op = ops[i]; if (gPMProfOn && gPMStatsPtr) #ifdef _MSC_VER gPMStatsPtr->markEvent(op.lbid, GetCurrentThreadId(), gSession, 'I'); #else gPMStatsPtr->markEvent(op.lbid, pthread_self(), gSession, 'I'); #endif HashObject_t fbIndex(op.lbid, op.ver, 0); filebuffer_pair_t pr = fbSet.insert(fbIndex); if (!pr.second) { if (gPMProfOn && gPMStatsPtr) #ifdef _MSC_VER gPMStatsPtr->markEvent(op.lbid, GetCurrentThreadId(), gSession, 'D'); #else gPMStatsPtr->markEvent(op.lbid, pthread_self(), gSession, 'D'); #endif continue; } //cout << "FBM: inserting <" << op.lbid << ", " << op.ver << endl; fCacheSize++; fBlksLoaded++; FBData_t fbdata = {op.lbid, op.ver, 0}; updateLRU(fbdata); pi = doBlockCopy(op.lbid, op.ver, op.data); HashObject_t &ref = const_cast<HashObject_t &>(*pr.first); ref.poolIdx = pi; fFBPool[pi].listLoc(fbList.begin()); if (gPMProfOn && gPMStatsPtr) #ifdef _MSC_VER gPMStatsPtr->markEvent(op.lbid, GetCurrentThreadId(), gSession, 'J'); #else gPMStatsPtr->markEvent(op.lbid, pthread_self(), gSession, 'J'); #endif ret++; } idbassert(fCacheSize <= maxCacheSize()); return ret; }
/* * search_data_from_cache - get data from cache * * Pamameters: * url: using for matching tag in cache * cache_resp: using for store reponse from cache * * Return: 1 - found in cache * 0 - not found in cache */ int search_data_from_cache(char *url, char *cache_resp) { dbg_printf("--------In search_data_from_cache function ---------\n"); int set_idx, line_idx; Cache_Set *set; for (set_idx = 0; set_idx < cache.num_sets; set_idx++) { set = &cache.set[set_idx]; for (line_idx = 0; line_idx < cache.num_lines; line_idx++) { Cache_Line *currLine = &set->line[line_idx]; // has invalid line if (0 == currLine->v && isLineFull == 1) { isLineFull = 0; } // search in cache line if(set->line[line_idx].v && (strcmp(set->line[line_idx].tag, url) == 0)) { dbg_printf("set->line[line_idx].tag: %s\n", set->line[line_idx].tag); dbg_printf("url: %s\n", url); // lock to prevent race condition P(&mutex); updateLRU(set, currLine, cache.num_lines); V(&mutex); // load response from cache strcpy(cache_resp, set->line[line_idx].block); return 1; } } } return 0; dbg_printf("--------In search_data_from_cache function END ---------\n"); }
/* * caching_from_server - caching data received from server * * Pamameters: * url: using for matching tag in cache * server_resp: using for store reponse from server */ void caching_from_server(char *url, char *server_resp) { dbg_printf("--------In caching_from_server function ---------\n"); int set_idx = 0; Cache_Set *currSet = &cache.set[set_idx]; Cache_Line *currLine; /* consider eviction */ if (isLineFull) { int idx_lru = getLRU(*currSet, cache.num_lines); currLine = &currSet->line[idx_lru]; } /* there's an empty line, no eviction */ else { int idx_empty_line = getEmptyLine(*currSet, cache.num_lines); if (-1 == idx_empty_line) { printf("Line is full, something wrong\n"); exit(-1); } currLine = &currSet->line[idx_empty_line]; } /* update cache line based on data from server */ strcpy(currLine->tag, url); strcpy(currLine->block, server_resp); dbg_printf("url: %s\n", url); dbg_printf("set->line[idx_lru].tag: %s\n", currLine->tag); if (currLine->v == 0) { currLine->v = 1; } updateLRU(currSet, currLine, cache.num_lines); dbg_printf("--------In caching_from_server function END ---------\n"); }
void simulator(int C, int K, int L){ int setSize = calculateSetSize(C, K, L); int lineSize = calculateLineSize(C, K, L); //First set of arrays for data int LRUArray[lineSize*setSize], tagArray[lineSize*setSize], validBitArray[lineSize*setSize]; //First set of arrays for data int dataLRUArray[lineSize*setSize], dataTagArray[lineSize*setSize], dataValidBitArray[lineSize*setSize]; //Second set of arrays for instruction int instructionLRUArray[lineSize*setSize], instructionTagArray[lineSize*setSize], instructionValidBitArray[lineSize*setSize]; //Initializes all array entries to 0 int i,j; //Initializing every LRU of the cache to a value between 0 - (lineSize-1) for(i = 0; i<lineSize; i++ ){ for(j = 0; j<setSize; j++){ LRUArray[i+j*lineSize] = i; validBitArray[i+j*lineSize] = 0; tagArray[i+j*lineSize] = 0; dataLRUArray[i+j*lineSize] = i; dataValidBitArray[i+j*lineSize] = 0; dataTagArray[i+j*lineSize] = 0; instructionLRUArray[i+j*lineSize] = i; instructionValidBitArray[i+j*lineSize] = 0; instructionTagArray[i+j*lineSize] = 0; } } int instruction, address, tag, set, setLine; double missNumber, totalMemoryReferences, dataMiss, instructionMiss, dataReferences, instructionReferences; //miss will take care of maintaining track of how many misses the simulator has, toatlIteratiosn just counts how many total addresses the simulator has. missNumber = 0; dataMiss = 0; instructionMiss = 0; dataReferences = 0; instructionReferences = 0; totalMemoryReferences = 0; instruction = 1; address = 0; FILE *ifp; //Pointer to a file is declared ifp = fopen("trace.txt", "r"); // ifp points to file // trace.txt, opened for // reading while (!feof(ifp)) { // exit if end-of-file reached fscanf(ifp, "%d %x", &instruction, &address); // read next line switch (instruction){ // cases 0 -3 run the same thing case 0: case 1: tag = decodeTag(address, C, K, L, setSize); set = decodeSet(address, C, K, L, setSize); //Printing information //printf("Address: %x \n Tag: %d \n Set: %d \n\n", address, tag, set); if((setLine = tagHit(dataTagArray, set, tag, lineSize)) > -1){ if(dataValid(dataValidBitArray, set, setLine, lineSize)>0){ updateLRU(dataLRUArray, set, setLine, lineSize); }else{ writeToAddress(dataTagArray, set, tag, setLine, lineSize); validateData(dataValidBitArray, set, setLine, lineSize); updateLRU(dataLRUArray, set, setLine, lineSize); dataMiss++; missNumber++; } }else{ setLine = writeToCache(dataTagArray, dataLRUArray, set, tag, lineSize); validateData(dataValidBitArray, set, setLine, lineSize); updateLRU(dataLRUArray, set, setLine, lineSize); dataMiss++; missNumber++; } dataReferences++; totalMemoryReferences++; break; case 2: tag = decodeTag(address, C, K, L, setSize); set = decodeSet(address, C, K, L, setSize); //Printing information //printf("Address: %x \n Tag: %d \n Set: %d \n\n", address, tag, set); if((setLine = tagHit(instructionTagArray, set, tag, lineSize)) > -1){ if(dataValid(instructionValidBitArray, set, setLine, lineSize)>0){ updateLRU(instructionLRUArray, set, setLine, lineSize); }else{ writeToAddress(instructionTagArray, set, tag, setLine, lineSize); validateData(instructionValidBitArray, set, setLine, lineSize); updateLRU(instructionLRUArray, set, setLine, lineSize); instructionMiss++; missNumber++; } }else{ setLine = writeToCache(instructionTagArray, LRUArray, set, tag, lineSize); validateData(instructionValidBitArray, set, setLine, lineSize); updateLRU(instructionLRUArray, set, setLine, lineSize); instructionMiss++; missNumber++; } instructionReferences++; totalMemoryReferences++; break; //End iteration //address++; case 3:break; case 4: clearCache(dataValidBitArray, lineSize, setSize); clearCache(instructionValidBitArray, lineSize, setSize); break; } } fclose(ifp); // Close file double missRate = missNumber/totalMemoryReferences*100; //printCache(tagArray, validBitArray, LRUArray, setSize, lineSize); printf("%.0f misses, ", missNumber); printf("%.0f total memory references, ", totalMemoryReferences); printf("%2.4f miss rate, \n\n", missRate); }
int main() { memset (L2cache, 0, sizeof (cacheLine)); // initialize the counters int refCount = 0; int readCount = 0; int writeCount = 0; int hitCount = 0; int missCount = 0; int hitM = 0; int hit = 0; int way; // initialize the input from the tracefile int n; // to handle the addr in hex, must be specified with prefix '0x' // it will be read as hex as long as the read uses %x instead of %d int addr; // initialize the LRU bits to the way setLRUbitsToWay(); // open the tracefile, make it available to 'r' read // open the output file to make it available to append each iteration's result ifp = fopen("testfile.txt", "r"); ofp = fopen("testout.txt", "a"); fprintf(ofp,"-----------------------------------------------------------------------------------------------------\n"); fflush(ofp); // set it up to read line by line // set n and addr accordingly while (fscanf(ifp, "%d %x\n", &n, &addr) != EOF) { // parse 32-bit hex address int tag = addr >> 20; int index = (addr >> 6) & 16383; // get 1 bit from the fifth position to check later whether 1 or 0 int byteSelect = (addr >> 5) & ~(~0 << 1); refCount++; fprintf(ofp,"Reference: %d\n",refCount); fflush(ofp); switch (n) { // the L1 cache makes a read request // n = 0 read data request from L1 cache // n = 2 instruction fetch (treated as a read request from L1 cache) case 0: case 2: readCount++; // determine whether this tag exists in the cache and, if so, which way way = checkTag(index, tag); // if the tag exists if (way == 0 || way == 1 || way == 2 || way == 3) { // this tag exists and it's valid as per its MESI bits int MESI = L2cache[index][way].MESIbits; if (MESI == M || MESI == E || MESI == S) { hitCount++; // update the LRU to set 'way' to least recently used updateLRU(index, way); dataToL1(byteSelect,index,tag,way); // MESI remains unchanged // copy the addr to address in the cacheLine struct for case 9 display L2cache[index][way].address = addr; } // this tag exists but it's been invalidated and can't be used else { missCount++; dataFromDRAM(addr,index,way,refCount); dataToL1(byteSelect,index,tag,way); // update LRU updateLRU(index, way); L2cache[index][way].MESIbits = E; L2cache[index][way].address = addr; } } // this tag simply doesn't exist in the cache in any form else { missCount++; // use the LRU bit to determine which way to evict way = checkLRU(index); // update LRU updateLRU(index, way); dataFromDRAM(addr,index,way,refCount); L2cache[index][way].tag = tag; dataToL1(byteSelect,index,tag,way); L2cache[index][way].MESIbits = E; L2cache[index][way].address = addr; } break; // 1 write data request from L1 cache case 1: writeCount++; // determine whether this tag exists in the cache and, if so, which way way = checkTag(index, tag); // if the tag exists if (way == 0 || way == 1 || way == 2 || way == 3) { // this tag exists so check if it's valid as per its MESI bits int MESI = L2cache[index][way].MESIbits; if (MESI == M || MESI == E || MESI == S) { hitCount++; // update the LRU to set 'way' to least recently used updateLRU(index, way); // set MESI to modified because only we have it now L2cache[index][way].MESIbits = E; // because L2 has everything in L1, we send contents of our L2 // from our copy of that index/way to the DRAM dataToDRAM(addr,index,way,refCount); L2cache[index][way].MESIbits = M; L2cache[index][way].address = addr; } // this tag exists but its MESI bits say invalid, needs to be updated // in this case we have to get the data from L1 and expand it to 64 bytes else { missCount++; // update LRU updateLRU(index, way); // set MESI to Modified L2cache[index][way].MESIbits = E; dataFromL1(index, way, addr, byteSelect); dataToDRAM(addr,index,way,refCount); // MESI = Exclusive after memory write L2cache[index][way].MESIbits = M; L2cache[index][way].address = addr; } } // this tag simply doesn't exist in the cache in any form // this covers the very unlikely odd case where L1 has what L2 doesn't else { missCount++; // use the LRU bit to determine which way to evict way = checkLRU(index); L2cache[index][way].MESIbits = E; dataFromL1(index, way, addr, byteSelect); L2cache[index][way].tag = tag; dataToDRAM(addr,index,way,refCount); // update LRU updateLRU(index, way); // MESI = Exclusive after memory write L2cache[index][way].MESIbits = M; L2cache[index][way].address = addr; } break; // 4 snooped a read request from another processor case 4: readCount++; // determine whether this tag exists in the cache and, if so, which way way = checkTag(index, tag); // if the tag exists if (way == 0 || way == 1 || way == 2 || way == 3) { // this tag exists so check if it's valid as per its MESI bits int MESI = L2cache[index][way].MESIbits; // if the tag exists but it's modified if (MESI == M) { hitCount++; hitM++; // first response is to read out our modified copy to other cache dataToSnooped(addr); // then we write to our L1, just in case, and on to DRAM dataToL1(byteSelect,index,tag,way); dataToDRAM(addr,index,way,refCount); // set MESI to shared after mem write to other processor completed L2cache[index][way].MESIbits = S; L2cache[index][way].address = addr; } // if the tag exists but it's exclusive else if (MESI == E || MESI == S) { hitCount++; hit++; dataToSnooped(addr); dataToL1(byteSelect,index,tag,way); // set MESI to shared after mem write to other processor completed L2cache[index][way].MESIbits = S; L2cache[index][way].address = addr; } // if the tag exists but it's invalid -- we don't have it else { missCount++; } } break; // 3 invalidate command or snooped write request case 3: way = checkTag(index, tag); // if the tag exists if (way == 0 || way == 1 || way == 2 || way == 3) { // this tag exists so check if it's valid as per its MESI bits int MESI = L2cache[index][way].MESIbits; if (MESI == I) { missCount++; } else if (MESI == M || MESI == E || MESI == S) { L2cache[index][way].MESIbits = I; hitCount++; L2cache[index][way].address = addr; } // if we don't have it, we do nothing } break; // snooped write request from another processor case 5: writeCount++; way = checkTag(index, tag); // if the tag exists if (way == 0 || way == 1 || way == 2 || way == 3) { // this tag exists so check if it's valid as per its MESI bits int MESI = L2cache[index][way].MESIbits; // if the tag exists but it's modified if (MESI == M || MESI == E || MESI == S) { hitCount++; L2cache[index][way].MESIbits = I; L2cache[index][way].address = addr; } else { missCount++; } // if we don't have it, we ignore entirely } else missCount++; break; // 6 snooped read for ownership request case 6: readCount++; way = checkTag(index, tag); // if the tag exists if (way == 0 || way == 1 || way == 2 || way == 3) { // this tag exists so check if it's valid as per its MESI bits int MESI = L2cache[index][way].MESIbits; // if the tag exists but it's modified, we can serve this request // before setting our MESI bits to invalid if (MESI == M || MESI == E || MESI == S) { hitCount++; if (MESI == M) { hitM++; } dataToSnooped(addr); invalidateInL1(addr); L2cache[index][way].MESIbits = I; // LRU update not necessary here because our algorithm checks for // empty (invalid MESI bit) lines first before checking LRU bits L2cache[index][way].address = addr; } else { missCount++; } // if we don't have it, we do nothing } break; // 8 clear the cache and refresh all states case 8: // Use the algorithm for n = 3||5 and step through all indices and ways. // No MESI, LRU, or counter updates here, and no display. way = 0; for (index = 0; index < 16384; index++) { L2cache[index][0].MESIbits = 3; L2cache[index][0].LRUbits = 0; L2cache[index][1].MESIbits = 3; L2cache[index][1].LRUbits = 1; L2cache[index][2].MESIbits = 3; L2cache[index][2].LRUbits = 2; L2cache[index][3].MESIbits = 3; L2cache[index][3].LRUbits = 3; L2cache[index][way].address = addr; } break; // 9 print everything, destroy nothing case 9: // Print contents of L2 cache in a pretty, pretty box to an output file ofpD = fopen("display.txt", "a"); fprintf(ofpD,"------------------------------------------------------\n"); fprintf(ofpD,"At reference number %d, the L2 cache looked like this.\n\n",refCount); fflush(ofpD); for (index = 0; index < 16384; index++) { for (way = 0; way < 4; way++) { if (L2cache[index][way].MESIbits != I) { fprintf(ofpD,"Index %d way %d tag %d LRUbits %d MESIbits %d\n\n",index,way,tag,L2cache[index][way].LRUbits,L2cache[index][way].MESIbits); fflush(ofpD); } } } break; // end switch statement } // print the counters in a neat form here at the end of each loop for testing float hitRatio; int total = hitCount + missCount; hitRatio = (float) hitCount / total; if ( n >= 0 && n < 8) { fprintf(ofp, "\ntag %d stored in index %d at way %d\n",tag,index,way); fflush(ofp); fprintf(ofp, "n address hitCount missCount LRU: way0 way1 way2 way3 MESI readCount writeCount hitRatio\n"); fflush(ofp); fprintf(ofp, "%-1d 0x%-8x %-8d %-15d %-5d %-4d %-4d %-4d %-4d %-9d %-11d %-4f\n", n, addr, hitCount, missCount, L2cache[index][0].LRUbits, L2cache[index][1].LRUbits, L2cache[index][2].LRUbits, L2cache[index][3].LRUbits, L2cache[index][way].MESIbits, readCount, writeCount, hitRatio); fflush(ofp); } else if (n == 8) { fprintf(ofp, "the MESI bits of every line in this cache were set to invalid\n"); fflush(ofp); } else if (n == 9) { fprintf(ofp, "all valid lines with contents, LRU bits, and MESI bits in display.txt\n"); fflush(ofp); } fprintf(ofp,"--------------------------------------------------------------------------------------------------\n"); fflush(ofp); // end while loop } float hitRatio = (float) hitCount / refCount; printf(" Total References: %d\n Reads: %d\n Writes: %d\n Hits: %d\n Misses %d\n Hit ratio: %f\n",refCount,readCount,writeCount,hitCount,missCount,hitRatio); return 0; // end of main() function }
void simulator(int C, int K, int L){ int setSize = calculateSetSize(C, K, L); int lineSize = calculateLineSize(C, K, L); int LRUArray[lineSize*setSize], tagArray[lineSize*setSize], validBitArray[lineSize*setSize]; //Initializes all array entries to 0 int i,j; //Initializing every LRU of the cache to a value between 0 - (lineSize-1) for(i = 0; i<lineSize; i++ ){ for(j = 0; j<setSize; j++){ LRUArray[i+j*lineSize] = i; validBitArray[i+j*lineSize] = 0; tagArray[i+j*lineSize] = 0; } } int iter, instruction, address, tag, set, setLine; double missNumber, totalMemoryReferences; //miss will take care of maintaining track of how many misses the simulator has, toatlIteratiosn just counts how many total addresses the simulator has. missNumber = 0; totalMemoryReferences = 0; instruction = 1; iter = 0; srand(4342); while(iter < 100000){ address = rand(); //printf("%d\n", address); switch (instruction){ // cases 0 -3 run the same thing case 0: case 1: case 2: tag = decodeTag(address, C, K, L, setSize); set = decodeSet(address, C, K, L, setSize); //Printing information //printf("Address: %x \n Tag: %d \n Set: %d \n\n", address, tag, set); if((setLine = tagHit(tagArray, set, tag, lineSize)) > -1){ if(dataValid(validBitArray, set, setLine, lineSize)>0){ updateLRU(LRUArray, set, setLine, lineSize); }else{ writeToAddress(tagArray, set, tag, setLine, lineSize); validateData(validBitArray, set, setLine, lineSize); updateLRU(LRUArray, set, setLine, lineSize); missNumber++; } }else{ setLine = writeToCache(tagArray, LRUArray, set, tag, lineSize); validateData(validBitArray, set, setLine, lineSize); updateLRU(LRUArray, set, setLine, lineSize); missNumber++; } break; case 3:break; case 4: clearCache(validBitArray, lineSize, setSize); break; } iter++; totalMemoryReferences++; } double missRate = missNumber/totalMemoryReferences*100; //printCache(tagArray, validBitArray, LRUArray, setSize, lineSize); printf("%.0f misses, ", missNumber); printf("%.0f total memory references, ", totalMemoryReferences); printf("%2.4f miss rate, \n\n", missRate); }