/* }}} */ Time_t StridePrefetcher::nextInvalidateSlot( const MemRequest *mreq) /* calculate next free time {{{1 */ { if (nextBuffSlot() > nextTableSlot()) return nextBuffSlot(); return nextTableSlot(); }
/* }}} */ Time_t StridePrefetcher::nextBusReadSlot( const MemRequest *mreq) /* calculate next free time {{{1 */ { return globalClock; if (nextBuffSlot() > nextTableSlot()) return nextBuffSlot(); return nextTableSlot(); }
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]); }
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); }
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); } } }
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))); } }