Exemple #1
0
/* }}} */
Time_t StridePrefetcher::nextInvalidateSlot( const MemRequest *mreq)
  /* calculate next free time {{{1 */
{
  if (nextBuffSlot() > nextTableSlot()) 
    return nextBuffSlot();
  
  return nextTableSlot();
}
Exemple #2
0
/* }}} */
Time_t StridePrefetcher::nextBusReadSlot(    const MemRequest *mreq)
  /* calculate next free time {{{1 */
{
  return globalClock;
  if (nextBuffSlot() > nextTableSlot()) 
    return nextBuffSlot();
  
  return nextTableSlot();
}
Exemple #3
0
void MarkovPrefetcher::insertTable(PAddr addr){
  uint32_t tag = table->calcTag(addr);
  Time_t lat = 0;

  if(tag){
    
    tEntry = table->readLine(addr);
    
    if(tEntry){
      lat = nextTableSlot() - globalClock;
      prefetch(tEntry->predAddr1,lat);
      
      lat = nextTableSlot() - globalClock;
      prefetch(tEntry->predAddr2,lat);
      
      lat = nextTableSlot() - globalClock;
      prefetch(tEntry->predAddr3,lat);

      lat = nextTableSlot() - globalClock;
      prefetch(tEntry->predAddr4,lat);
      

      //LOG("Prefetch %d", tEntry->predAddr1);
      //LOG("Prefetch %d", tEntry->predAddr2);
    }else{
      tEntry = table->fillLine(addr);
    }
    
    LOG("last Addr %d", lastAddr);    
    tEntry = table->readLine(lastAddr);
    
    //update last entry
    tEntry->predAddr4 = tEntry->predAddr3;
    tEntry->predAddr3 = tEntry->predAddr2;
    tEntry->predAddr2 = tEntry->predAddr1;
    tEntry->predAddr1 = addr;
    
    lastAddr = addr;
  }
}
void AlwaysPrefetch::read(MemRequest *mreq)
{
  uint32_t paddr = mreq->getPAddr() & defaultMask;
  bLine *l = buff->readLine(paddr);

  if(l) { //hit
    LOG("NLAP: hit on [%08lx]", (long unsigned int) paddr);
    hit.inc();    
    mreq->goUpAbs(nextBuffSlot());
    return;
  }

  penFetchSet::iterator it = pendingFetches.find(paddr);
  if(it != pendingFetches.end()) { // half-miss
    LOG("NLAP: half-miss on %08lx",(long unsigned int)  paddr);
    penReqMapper::iterator itR = pendingRequests.find(paddr);
    halfMiss.inc();
    if (itR == pendingRequests.end()) {
      pendingRequests[paddr] = activeMemReqPool.out();
      itR = pendingRequests.find(paddr);
    }

    I(itR != pendingRequests.end());
    
    (*itR).second->push(mreq);
    //prefetch(paddr+lineSize, 0); 
    //prefetch( paddr + buff->getLineSize(), 0 ); 
    return;
  }

  LOG("NLAP: miss on [%08lx]", (long unsigned int) paddr);
  miss.inc();

  Time_t lat = nextTableSlot() - globalClock;    

  prefetch(paddr+(buff->getLineSize()), lat);
  lat = nextTableSlot() - globalClock;    
  prefetch(paddr+(2*buff->getLineSize()), lat); 
  mreq->goDown(0, lowerLevel[0]);
}
Exemple #5
0
void StridePrefetcher::learnHit(PAddr addr)
{
  uint paddr = addr & defaultMask;
  pEntry *pe = table->readLine(paddr);
  Time_t lat = nextTableSlot() - globalClock;

  if(pe == 0) // this hit in the buffer came from data 
    return;   // from a no longer active stream

  prefetch(pe, lat + learnHitDelay); 
  pe->setTag(table->calcTag(pe->nextAddr(table)));
  LOG("SP:prefetching more: addr=%08lx", paddr + pe->stride);
}
Exemple #6
0
void StridePrefetcher::learnMiss(AddrType addr) {

  AddrType paddr = addr & defaultMask;
  Time_t lat = nextTableSlot() - globalClock;

  bool foundUnitStride = false;
  uint32_t newStride = 0;
  uint32_t minDelta = (uint32_t) -1;
  bool goingUp = true;

  if(lastMissesQ.empty()) {
    lastMissesQ.push_back(paddr);
    return;
  }

  // man, this is baad. i have to do a better search here
  std::deque<AddrType>::iterator it = lastMissesQ.begin();
  while(it != lastMissesQ.end()) {

   uint32_t delta;
    if(paddr < (*it)) {
      goingUp = false;
      delta = (*it) - paddr;
    } else {
      goingUp = true;
      delta = paddr - (*it);
    }
    minDelta = (delta < minDelta ? delta : minDelta);

    if((*it) == paddr - buff->getLineSize() || (*it) == paddr + buff->getLineSize()) {
      foundUnitStride = true;
      break;
    }
    it++;
  }

  // putting the new miss in the queue after we computed the stride
  lastMissesQ.push_back(paddr);

  if(lastMissesQ.size() > missWindow)
    lastMissesQ.pop_front();

  if(foundUnitStride) {
    unitStrideStreams.inc();
    newStride = buff->getLineSize();
  } else {
    nonUnitStrideStreams.inc();
    newStride = minDelta;
  }

  if(newStride == 0 || newStride == (uint32_t) -1 || newStride > maxStride) {
    ignoredStreams.inc();
    return;
  }

  AddrType nextAddr = goingUp ? paddr + newStride : paddr - newStride;

  if(!table->readLine(nextAddr) && !table->readLine(paddr)) {
    pEntry *pe = table->fillLine(paddr);
    pe->stride = newStride;
    pe->goingUp = goingUp;
  }

  if (pendingRequests> MaxPendingRequests) {
    // FIXME: fetch the depth following addresses

    AddrType paddr = nextAddr & defaultMask;
    bLine *l = buff->readLine(paddr);
    if (l==0) {
      MemRequest *mreq = MemRequest::createRead(this, nextAddr, 0);
      router->fwdBusRead(mreq, missDelay); 
    }
  }

}
Exemple #7
0
void StridePrefetcher::learnMiss(PAddr addr)
{
  uint paddr = addr & defaultMask;
  Time_t lat = nextTableSlot() - globalClock;
  bool foundUnitStride = false;
  uint newStride = 0;
  uint minDelta = (uint) -1;
  bool goingUp = true;

  if(lastMissesQ.empty()) {
    lastMissesQ.push_back(paddr);
    return;
  }

  // man, this is baad. i have to do a better search here
  std::deque<PAddr>::iterator it = lastMissesQ.begin();
  while(it != lastMissesQ.end()) {

	 uint delta;
    if(paddr < (*it)) {
      goingUp = false;
      delta = (*it) - paddr;
    } else {
      goingUp = true;
      delta = paddr - (*it);
    }
    minDelta = (delta < minDelta ? delta : minDelta);

    if((*it) == paddr - buff->getLineSize() || (*it) == paddr + buff->getLineSize()) {
      foundUnitStride = true;
      break;
    }

    it++;
  }
  
  // putting the new miss in the queue after we computed the stride
  lastMissesQ.push_back(paddr);
  if(lastMissesQ.size() > missWindow)
    lastMissesQ.pop_front();
  
  if(foundUnitStride) {
    unitStrideStreams.inc();
    newStride = buff->getLineSize();
  } else {
    nonUnitStrideStreams.inc();
    newStride = minDelta;
  }

  LOG("minDelta = %ld", minDelta);
  
  if(newStride == 0 || newStride == (uint) -1 || newStride > maxStride) {
    ignoredStreams.inc();
    return;
  }

  PAddr nextAddr = goingUp ? paddr + newStride : paddr - newStride;

  // TODO: do a better check if there is an overlapping stream
  if(!table->readLine(nextAddr) && !table->readLine(paddr)) {
    pEntry *pe = table->fillLine(paddr);
    pe->stride = newStride;
    pe->goingUp = goingUp;
    LOG("SP: new stream. stride=%d paddr=%08lx nextAddr=%08lx %s", (int) newStride, paddr, nextAddr, goingUp ? "UP" : "DOWN");
    prefetch(pe, lat + learnMissDelay); 
    pe->setTag(table->calcTag(pe->nextAddr(table)));
  }
}