void SingleMSHR<Addr_t, Cache_t>::putEntry(MSHRentry<Addr_t> &me) { I(ms.find(me.getLineAddr()) == ms.end()); I(nFreeEntries > 0); ms[me.getLineAddr()] = me; ms[me.getLineAddr()].adjustParameters(getnReads(), getnWrites()); MSHRentry<Addr_t> &pme = ms[me.getLineAddr()]; bf.insert(pme.getLineAddr()); nOutsReqs += pme.getPendingReqs(); nFreeEntries--; updateOccHistogram(); occStats->incRdReqs(me.getUsedReads()); #ifdef MSHR_EXTRAOCCSTATS occStats->sampleEntry(me.getLineAddr()); #endif if( ! pme.hasFreeReads() ) { nFullReadEntries++; } if( ! pme.hasFreeWrites() ) { nFullWriteEntries++; } I(nFreeEntries >=0); }
void SingleMSHR<Addr_t, Cache_t>::dropEntry(Addr_t lineAddr) { MSHRit it = ms.find(lineAddr); I(it != ms.end()); (*it).second.displace(); if( ! (*it).second.hasFreeReads() ) { nFullReadEntries--; } if( ! (*it).second.hasFreeWrites() ) { nFullWriteEntries--; } nOutsReqs -= ( (*it).second.getPendingReqs() ); nFreeEntries++; updateOccHistogram(); occStats->decRdReqs((*it).second.getUsedReads()); #ifdef MSHR_EXTRAOCCSTATS if((*it).second.getUsedReads() == 0 && (*it).second.getUsedWrites() > 0) { occStats->retireWrEntry((*it).second.getLineAddr()); } else if( (*it).second.getUsedReads() > 0 && (*it).second.getUsedWrites() == 0 ) { occStats->retireRdEntry((*it).second.getLineAddr()); } else { I( (*it).second.getUsedWrites() > 0 ); I( (*it).second.getUsedReads() > 0 ); occStats->retireRdWrEntry((*it).second.getLineAddr()); } #endif ms.erase(it); bf.remove(lineAddr); }
bool SingleMSHR<Addr_t, Cache_t>::issue(Addr_t paddr, MemOperation mo) { MSHRit it = ms.find(calcLineAddr(paddr)); nUse.inc(); if(mo == MemRead) nUseReads.inc(); if(mo == MemWrite) nUseWrites.inc(); if(!overflow.empty()) { return false; } I(nFreeEntries >= 0 && nFreeEntries <=nEntries); if(it == ms.end()) { if(nFreeEntries > 0) { ms[calcLineAddr(paddr)].firstRequest(paddr, calcLineAddr(paddr), nReads, nWrites, mo); bf.insert(calcLineAddr(paddr)); nFreeEntries--; #ifdef MSHR_BASICOCCSTATS updateOccHistogram(); #endif nOutsReqs++; #ifdef MSHR_BASICOCCSTATS if(mo == MemRead) occStats->incRdReqs(); #endif nIssuesNewEntry.inc(); avgQueueSize.sample(0); checkSubEntries(paddr, mo); #ifdef MSHR_EXTRAOCCSTATS occStats->sampleEntry( calcLineAddr(paddr) ); #endif return true; } } return false; }
bool SingleMSHR<Addr_t, Cache_t>::retire(Addr_t paddr) { bool rmEntry = false; MSHRit it = ms.find(calcLineAddr(paddr)); I(it != ms.end()); I(calcLineAddr(paddr) == (*it).second.getLineAddr()); maxOutsReqs.sample(nOutsReqs); nOutsReqs--; //MSG("[%llu] nFullSubE=%d a=%lu",globalClock,nFullReadEntries,calcLineAddr(paddr)); rmEntry = (*it).second.retire(); if(rmEntry) { // the last pending request for the MSHRentry was completed // recycle the entry nRetiredEntries.inc(); avgReqsPerLine.sample((*it).second.getUsedReads() + (*it).second.getUsedWrites()); maxUsedEntries.sample(nEntries - nFreeEntries); avgWritesPerLine.sample((*it).second.getUsedWrites()); avgWritesPerLineComb.sample((*it).second.getNWrittenWords()); occStats->decRdReqs((*it).second.getUsedReads()); if((*it).second.getUsedWrites() > 0) nRetiredEntriesWritten.inc(); if( ! (*it).second.hasFreeReads() ) { nFullReadEntries--; I(nFullReadEntries>=0); } if( ! (*it).second.hasFreeWrites() ) { nFullWriteEntries--; I(nFullWriteEntries>=0); } if((*it).second.isL2Hit()) occStats->avgReadSubentriesL2Hit.sample((*it).second.getUsedReads()); else occStats->avgReadSubentriesL2Miss.sample((*it).second.getUsedReads()); #ifdef MSHR_EXTRAOCCSTATS // extra MSHR occ stats occStats->subEntriesHist.sample((*it).second.getUsedReads()+ (*it).second.getUsedWrites(), 1); occStats->subEntriesReadsHist.sample((*it).second.getUsedReads(), 1); occStats->subEntriesWritesHist.sample((*it).second.getUsedWrites(), 1); occStats->subEntriesWritesHistComb.sample((*it).second.getNWrittenWords(), 1); occStats->subEntriesHistComb.sample((*it).second.getUsedReads()+ (*it).second.getNWrittenWords(), 1); if((*it).second.getUsedReads() == 0 && (*it).second.getUsedWrites() > 0) { nOnlyWrites.inc(); occStats->retireWrEntry((*it).second.getLineAddr()); } else if( (*it).second.getUsedReads() > 0 && (*it).second.getUsedWrites() == 0 ) { occStats->retireRdEntry((*it).second.getLineAddr()); } else { I( (*it).second.getUsedWrites() > 0 ); I( (*it).second.getUsedReads() > 0 ); occStats->retireRdWrEntry((*it).second.getLineAddr()); } #endif nFreeEntries++; updateOccHistogram(); bf.remove((*it).second.getLineAddr()); ms.erase(it); } checkOverflow(); return rmEntry; }
void SingleMSHR<Addr_t, Cache_t>::checkOverflow() { if(overflow.empty()) //nothing to do return; if(checkingOverflow) // i am already checking the overflow return; I(!overflow.empty()); I(!checkingOverflow); checkingOverflow = true; int nConsumed = 0; do { OverflowField f = overflow.front(); MSHRit it = ms.find(calcLineAddr(f.paddr)); if(it == ms.end()) { if(nFreeEntries > 0) { ms[calcLineAddr(f.paddr)].firstRequest(f.paddr, calcLineAddr(f.paddr), nReads, nWrites, f.mo); checkSubEntries(f.paddr, f.mo); #ifdef MSHR_EXTRAOCCSTATS occStats->sampleEntry( calcLineAddr( f.paddr ) ); #endif bf.insert(calcLineAddr(f.paddr)); nFreeEntries--; updateOccHistogram(); nConsumed++; nOutsReqs++; if(f.mo == MemRead) occStats->incRdReqs(); f.ovflwcb->call(); f.cb->destroy(); overflow.pop_front(); nIssuesNewEntry.inc(); avgQueueSize.sample(0); } else { break; } } else { // just try to add the entry if((*it).second.addRequest(f.paddr, f.cb, f.mo)) { // succesfully accepted entry, but no need to call the callback // since there was already an entry pending for the same line avgQueueSize.sample((*it).second.getPendingReqs() - 1); f.ovflwcb->destroy(); overflow.pop_front(); nOutsReqs++; if(f.mo == MemRead) occStats->incRdReqs(); checkSubEntries(f.paddr, f.mo); //MSG("[%llu] nFullRd=%d nFullWr=%d a:%lu",globalClock, // nFullReadEntries,nFullWriteEntries,calcLineAddr(f.paddr)); } else { break; } } } while(!overflow.empty()); if(nConsumed) avgOverflowConsumptions.sample(nConsumed); checkingOverflow = false; }