summaryrefslogtreecommitdiff
path: root/src/mem/cache/prefetch/base.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/cache/prefetch/base.cc')
-rw-r--r--src/mem/cache/prefetch/base.cc156
1 files changed, 89 insertions, 67 deletions
diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc
index a7e6cfdfc..365ce6727 100644
--- a/src/mem/cache/prefetch/base.cc
+++ b/src/mem/cache/prefetch/base.cc
@@ -33,6 +33,7 @@
* Hardware Prefetcher Definition.
*/
+#include "arch/isa_traits.hh"
#include "base/trace.hh"
#include "mem/cache/base.hh"
#include "mem/cache/prefetch/base.hh"
@@ -43,7 +44,7 @@ BasePrefetcher::BasePrefetcher(const BaseCacheParams *p)
: size(p->prefetcher_size), pageStop(!p->prefetch_past_page),
serialSquash(p->prefetch_serial_squash),
cacheCheckPush(p->prefetch_cache_check_push),
- only_data(p->prefetch_data_accesses_only)
+ onlyData(p->prefetch_data_accesses_only)
{
}
@@ -52,6 +53,7 @@ BasePrefetcher::setCache(BaseCache *_cache)
{
cache = _cache;
blkSize = cache->getBlockSize();
+ _name = cache->name() + "-pf";
}
void
@@ -99,7 +101,8 @@ BasePrefetcher::regStats(const std::string &name)
pfSquashed
.name(name + ".prefetcher.num_hwpf_squashed_from_miss")
- .desc("number of hwpf that got squashed due to a miss aborting calculation time")
+ .desc("number of hwpf that got squashed due to a miss "
+ "aborting calculation time")
;
}
@@ -126,60 +129,79 @@ BasePrefetcher::inMissQueue(Addr addr)
PacketPtr
BasePrefetcher::getPacket()
{
- DPRINTF(HWPrefetch, "%s:Requesting a hw_pf to issue\n", cache->name());
+ DPRINTF(HWPrefetch, "Requesting a hw_pf to issue\n");
if (pf.empty()) {
- DPRINTF(HWPrefetch, "%s:No HW_PF found\n", cache->name());
+ DPRINTF(HWPrefetch, "No HW_PF found\n");
return NULL;
}
PacketPtr pkt;
- bool keepTrying = false;
+ bool keep_trying = false;
do {
pkt = *pf.begin();
pf.pop_front();
if (!cacheCheckPush) {
- keepTrying = cache->inCache(pkt->getAddr());
+ keep_trying = cache->inCache(pkt->getAddr());
}
+
+ if (keep_trying) {
+ DPRINTF(HWPrefetch, "addr 0x%x in cache, skipping\n",
+ pkt->getAddr());
+ delete pkt->req;
+ delete pkt;
+ }
+
if (pf.empty()) {
cache->deassertMemSideBusRequest(BaseCache::Request_PF);
- if (keepTrying) return NULL; //None left, all were in cache
+ if (keep_trying) {
+ return NULL; // None left, all were in cache
+ }
}
- } while (keepTrying);
+ } while (keep_trying);
pfIssued++;
+ assert(pkt != NULL);
+ DPRINTF(HWPrefetch, "returning 0x%x\n", pkt->getAddr());
return pkt;
}
-void
-BasePrefetcher::handleMiss(PacketPtr &pkt, Tick time)
+
+Tick
+BasePrefetcher::notify(PacketPtr &pkt, Tick time)
{
- if (!pkt->req->isUncacheable() && !(pkt->req->isInstRead() && only_data))
- {
- //Calculate the blk address
- Addr blkAddr = pkt->getAddr() & ~(Addr)(blkSize-1);
+ if (!pkt->req->isUncacheable() && !(pkt->req->isInstRead() && onlyData)) {
+ // Calculate the blk address
+ Addr blk_addr = pkt->getAddr() & ~(Addr)(blkSize-1);
- //Check if miss is in pfq, if so remove it
- std::list<PacketPtr>::iterator iter = inPrefetch(blkAddr);
+ // Check if miss is in pfq, if so remove it
+ std::list<PacketPtr>::iterator iter = inPrefetch(blk_addr);
if (iter != pf.end()) {
- DPRINTF(HWPrefetch, "%s:Saw a miss to a queued prefetch, removing it\n", cache->name());
+ DPRINTF(HWPrefetch, "Saw a miss to a queued prefetch addr: "
+ "0x%x, removing it\n", blk_addr);
pfRemovedMSHR++;
+ delete (*iter)->req;
+ delete (*iter);
pf.erase(iter);
if (pf.empty())
cache->deassertMemSideBusRequest(BaseCache::Request_PF);
}
- //Remove anything in queue with delay older than time
- //since everything is inserted in time order, start from end
- //and work until pf.empty() or time is earlier
- //This is done to emulate Aborting the previous work on a new miss
- //Needed for serial calculators like GHB
+ // Remove anything in queue with delay older than time
+ // since everything is inserted in time order, start from end
+ // and work until pf.empty() or time is earlier
+ // This is done to emulate Aborting the previous work on a new miss
+ // Needed for serial calculators like GHB
if (serialSquash) {
iter = pf.end();
iter--;
while (!pf.empty() && ((*iter)->time >= time)) {
pfSquashed++;
- pf.pop_back();
+ DPRINTF(HWPrefetch, "Squashing old prefetch addr: 0x%x\n",
+ (*iter)->getAddr());
+ delete (*iter)->req;
+ delete (*iter);
+ pf.erase(iter);
iter--;
}
if (pf.empty())
@@ -191,74 +213,70 @@ BasePrefetcher::handleMiss(PacketPtr &pkt, Tick time)
std::list<Tick> delays;
calculatePrefetch(pkt, addresses, delays);
- std::list<Addr>::iterator addr = addresses.begin();
- std::list<Tick>::iterator delay = delays.begin();
- while (addr != addresses.end())
- {
- DPRINTF(HWPrefetch, "%s:Found a pf canidate, inserting into prefetch queue\n", cache->name());
- //temp calc this here...
+ std::list<Addr>::iterator addrIter = addresses.begin();
+ std::list<Tick>::iterator delayIter = delays.begin();
+ for (; addrIter != addresses.end(); ++addrIter, ++delayIter) {
+ Addr addr = *addrIter;
+
pfIdentified++;
- //create a prefetch memreq
- Request * prefetchReq = new Request(*addr, blkSize, 0);
- PacketPtr prefetch;
- prefetch = new Packet(prefetchReq, MemCmd::HardPFReq, -1);
- prefetch->allocate();
- prefetch->req->setThreadContext(pkt->req->contextId(),
- pkt->req->threadId());
- prefetch->time = time + (*delay); //@todo ADD LATENCY HERE
- //... initialize
+ DPRINTF(HWPrefetch, "Found a pf candidate addr: 0x%x, "
+ "inserting into prefetch queue with delay %d time %d\n",
+ addr, *delayIter, time);
- //Check if it is already in the cache
- if (cacheCheckPush) {
- if (cache->inCache(prefetch->getAddr())) {
- addr++;
- delay++;
- continue;
- }
+ // Check if it is already in the cache
+ if (cacheCheckPush && cache->inCache(addr)) {
+ DPRINTF(HWPrefetch, "Prefetch addr already in cache\n");
+ continue;
}
- //Check if it is already in the miss_queue
- if (cache->inMissQueue(prefetch->getAddr())) {
- addr++;
- delay++;
+ // Check if it is already in the miss_queue
+ if (cache->inMissQueue(addr)) {
+ DPRINTF(HWPrefetch, "Prefetch addr already in miss queue\n");
continue;
}
- //Check if it is already in the pf buffer
- if (inPrefetch(prefetch->getAddr()) != pf.end()) {
+ // Check if it is already in the pf buffer
+ if (inPrefetch(addr) != pf.end()) {
pfBufferHit++;
- addr++;
- delay++;
+ DPRINTF(HWPrefetch, "Prefetch addr already in pf buffer\n");
continue;
}
- //We just remove the head if we are full
- if (pf.size() == size)
- {
- DPRINTF(HWPrefetch, "%s:Inserting into prefetch queue, it was full removing oldest\n", cache->name());
+ // create a prefetch memreq
+ Request *prefetchReq = new Request(*addrIter, blkSize, 0);
+ PacketPtr prefetch =
+ new Packet(prefetchReq, MemCmd::HardPFReq, Packet::Broadcast);
+ prefetch->allocate();
+ prefetch->req->setThreadContext(pkt->req->contextId(),
+ pkt->req->threadId());
+
+ prefetch->time = time + (*delayIter); // @todo ADD LATENCY HERE
+
+ // We just remove the head if we are full
+ if (pf.size() == size) {
pfRemovedFull++;
+ PacketPtr old_pkt = *pf.begin();
+ DPRINTF(HWPrefetch, "Prefetch queue full, "
+ "removing oldest 0x%x\n", old_pkt->getAddr());
+ delete old_pkt->req;
+ delete old_pkt;
pf.pop_front();
}
pf.push_back(prefetch);
-
- //Make sure to request the bus, with proper delay
- cache->requestMemSideBus(BaseCache::Request_PF, prefetch->time);
-
- //Increment through the list
- addr++;
- delay++;
}
}
+
+ return pf.empty() ? 0 : pf.front()->time;
}
std::list<PacketPtr>::iterator
BasePrefetcher::inPrefetch(Addr address)
{
- //Guaranteed to only be one match, we always check before inserting
+ // Guaranteed to only be one match, we always check before inserting
std::list<PacketPtr>::iterator iter;
- for (iter=pf.begin(); iter != pf.end(); iter++) {
+ for (iter = pf.begin(); iter != pf.end(); iter++) {
if (((*iter)->getAddr() & ~(Addr)(blkSize-1)) == address) {
return iter;
}
@@ -266,4 +284,8 @@ BasePrefetcher::inPrefetch(Addr address)
return pf.end();
}
-
+bool
+BasePrefetcher::samePage(Addr a, Addr b)
+{
+ return roundDown(a, TheISA::VMPageSize) == roundDown(b, TheISA::VMPageSize);
+}