mem-cache: Fixes to PIF prefetcher
authorDaniel R. Carvalho <odanrc@yahoo.com.br>
Fri, 1 May 2020 15:15:42 +0000 (17:15 +0200)
committerDaniel Carvalho <odanrc@yahoo.com.br>
Mon, 4 May 2020 10:29:03 +0000 (10:29 +0000)
The temporal compactor was never initialized.

There were more possible indexes to the prec/succ vectors than
entries, so a block distance of zero would seg fault.

When checking for an address the wrong vector was being used.

From the original paper, "The prediction mechanism searches for
the PC of the accessed instruction in the index table"

Change-Id: I3c3aceac3c0adbbe8aef5c634c88cb35ba7487be
Signed-off-by: Daniel R. Carvalho <odanrc@yahoo.com.br>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/28487
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/mem/cache/prefetch/pif.cc

index 6a2983b1b39e308519ac29fe7595d396e246a70d..c557bd29f15eea138418ab1404585f331e05b968 100644 (file)
@@ -75,12 +75,12 @@ PIF::CompactorEntry::inSameSpatialRegion(Addr pc,
     Addr blk_distance = distanceFromTrigger(pc, log_blk_size);
 
     bool hit = (pc > trigger) ?
-        (succ.size() >= blk_distance) : (prec.size() >= blk_distance);
+        (succ.size() > blk_distance) : (prec.size() > blk_distance);
     if (hit && update) {
         if (pc > trigger) {
-            succ[blk_distance - 1] = true;
+            succ[blk_distance] = true;
         } else if (pc < trigger) {
-            prec[blk_distance - 1] = true;
+            prec[blk_distance] = true;
         }
     }
     return hit;
@@ -93,9 +93,9 @@ PIF::CompactorEntry::hasAddress(Addr target,
     Addr blk_distance = distanceFromTrigger(target, log_blk_size);
     bool hit = false;
     if (target > trigger) {
-        hit = blk_distance <= succ.size() && succ[blk_distance - 1];
+        hit = blk_distance < succ.size() && succ[blk_distance];
     } else if (target < trigger) {
-        hit = blk_distance <= prec.size() && succ[blk_distance - 1];
+        hit = blk_distance < prec.size() && prec[blk_distance];
     } else {
         hit = true;
     }
@@ -134,6 +134,7 @@ PIF::notifyRetiredInst(const Addr pc)
     // First access to the prefetcher
     if (temporalCompactor.size() == 0) {
         spatialCompactor = CompactorEntry(pc, precSize, succSize);
+        temporalCompactor.push_back(spatialCompactor);
     } else {
         // If the PC of the instruction retired is in the same spatial region
         // than the last trigger address, update the bit vectors based on the
@@ -195,12 +196,16 @@ void
 PIF::calculatePrefetch(const PrefetchInfo &pfi,
     std::vector<AddrPriority> &addresses)
 {
-    const Addr addr = pfi.getAddr();
+    if (!pfi.hasPC()) {
+        return;
+    }
+
+    const Addr pc = pfi.getPC();
 
     // First check if the access has been prefetched, this is done by
     // comparing the access against the active Stream Address Buffers
     for (auto &sabEntry : streamAddressBuffer) {
-        if (sabEntry->hasAddress(addr, lBlkSize)) {
+        if (sabEntry->hasAddress(pc, lBlkSize)) {
             sabEntry++;
             sabEntry->getPredictedAddresses(lBlkSize, addresses);
             // We are done
@@ -210,7 +215,7 @@ PIF::calculatePrefetch(const PrefetchInfo &pfi,
 
     // Check if a valid entry in the 'index' table is found and allocate a new
     // active prediction stream
-    IndexEntry *idx_entry = index.findEntry(addr, /* unused */ false);
+    IndexEntry *idx_entry = index.findEntry(pc, /* unused */ false);
 
     if (idx_entry != nullptr) {
         index.accessEntry(idx_entry);