Пример #1
0
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;
}
Пример #2
0
void SingleMSHR<Addr_t, Cache_t>::addEntry(Addr_t paddr, CallbackBase *c,
                                           CallbackBase *ovflwc, MemOperation mo)
{
  MSHRit it = ms.find(calcLineAddr(paddr));
  I(ovflwc); // for single MSHR, overflow handler REQUIRED!

  if(!overflow.empty()) {
    toOverflow(paddr, c, ovflwc, mo);
    return;
  }

  if(it == ms.end())  {// we must be overflowing because the issue did not happen
    toOverflow(paddr, c, ovflwc, mo);
    return;
  }

  I(it != ms.end());

  if((*it).second.addRequest(paddr, c, mo)) {
    // ok, the addrequest succeeded, the request was added
    avgQueueSize.sample((*it).second.getPendingReqs() - 1);
    nOutsReqs++;

#ifdef MSHR_BASICOCCSTATS
    if(mo == MemRead)
      occStats->incRdReqs();
#endif

    // there was no overflow, so the callback needs to be destroyed
    ovflwc->destroy();
    // check to see if we have filled up the subentries
    checkSubEntries(paddr, mo);

    //MSG("[%llu] nFullRd=%d nFullWr=%d a:%lu",globalClock,
    //      nFullReadEntries,nFullWriteEntries, calcLineAddr(paddr));
    return;
  } else {
    // too many oustanding requests to the same line already. send to overflow
    toOverflow(paddr, c, ovflwc, mo);
    return;
  }
}
Пример #3
0
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;
}