mem-cache: Fix invalid whenReady
authorDaniel R. Carvalho <odanrc@yahoo.com.br>
Mon, 12 Aug 2019 22:15:37 +0000 (00:15 +0200)
committerDaniel Carvalho <odanrc@yahoo.com.br>
Tue, 1 Oct 2019 06:19:38 +0000 (06:19 +0000)
When a writeback needs to be allocated the whenReady field of the
block is not set, and therefore its access latency calculation
uses the previously invalidated value (MaxTick), significantly
delaying execution.

This is fixed by assuming that the data write portion of a write
access is done regardless of previous writes, and that only the
tag latency is important for the critical path latency calculation.

Change-Id: I739132a2deab6eb4c46d084f4ee6dd65177873fd
Signed-off-by: Daniel R. Carvalho <odanrc@yahoo.com.br>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20068
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>

src/mem/cache/base.cc
src/mem/cache/cache_blk.hh

index 20266963ab8810fa98b3c797513a35bd73752d02..fcf03741c5eea503cc3648015a0b922d1f9b819f 100644 (file)
@@ -1094,6 +1094,11 @@ BaseCache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
         }
     }
 
+    // The critical latency part of a write depends only on the tag access
+    if (pkt->isWrite()) {
+        lat = calculateTagOnlyLatency(pkt->headerDelay, tag_latency);
+    }
+
     // Writeback handling is special case.  We can write the block into
     // the cache without having a writeable copy (or any copy at all).
     if (pkt->isWriteback()) {
@@ -1113,8 +1118,6 @@ BaseCache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
             // and we just had to wait for the time to find a match in the
             // MSHR. As of now assume a mshr queue search takes as long as
             // a tag lookup for simplicity.
-            lat = calculateTagOnlyLatency(pkt->headerDelay, tag_latency);
-
             return true;
         }
 
@@ -1124,11 +1127,6 @@ BaseCache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
             if (!blk) {
                 // no replaceable block available: give up, fwd to next level.
                 incMissCount(pkt);
-
-                // A writeback searches for the block, then writes the data.
-                // As the block could not be found, it was a tag-only access.
-                lat = calculateTagOnlyLatency(pkt->headerDelay, tag_latency);
-
                 return false;
             }
 
@@ -1140,14 +1138,6 @@ BaseCache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
             // If that is the case we might need to evict blocks.
             if (!updateCompressionData(blk, pkt->getConstPtr<uint64_t>(),
                 writebacks)) {
-                // This is a failed data expansion (write), which happened
-                // after finding the replacement entries and accessing the
-                // block's data. There were no replaceable entries available
-                // to make room for the expanded block, and since it does not
-                // fit anymore and it has been properly updated to contain
-                // the new data, forward it to the next level
-                lat = calculateAccessLatency(blk, pkt->headerDelay,
-                                             tag_latency);
                 invalidateBlock(blk);
                 return false;
             }
@@ -1171,9 +1161,6 @@ BaseCache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
         DPRINTF(Cache, "%s new state is %s\n", __func__, blk->print());
         incHitCount(pkt);
 
-        // A writeback searches for the block, then writes the data
-        lat = calculateAccessLatency(blk, pkt->headerDelay, tag_latency);
-
         // When the packet metadata arrives, the tag lookup will be done while
         // the payload is arriving. Then the block will be ready to access as
         // soon as the fill is done
@@ -1206,10 +1193,6 @@ BaseCache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
 
         if (!blk) {
             if (pkt->writeThrough()) {
-                // A writeback searches for the block, then writes the data.
-                // As the block could not be found, it was a tag-only access.
-                lat = calculateTagOnlyLatency(pkt->headerDelay, tag_latency);
-
                 // if this is a write through packet, we don't try to
                 // allocate if the block is not present
                 return false;
@@ -1220,13 +1203,6 @@ BaseCache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
                     // no replaceable block available: give up, fwd to
                     // next level.
                     incMissCount(pkt);
-
-                    // A writeback searches for the block, then writes the
-                    // data. As the block could not be found, it was a tag-only
-                    // access.
-                    lat = calculateTagOnlyLatency(pkt->headerDelay,
-                                                  tag_latency);
-
                     return false;
                 }
 
@@ -1239,14 +1215,6 @@ BaseCache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
             // If that is the case we might need to evict blocks.
             if (!updateCompressionData(blk, pkt->getConstPtr<uint64_t>(),
                 writebacks)) {
-                // This is a failed data expansion (write), which happened
-                // after finding the replacement entries and accessing the
-                // block's data. There were no replaceable entries available
-                // to make room for the expanded block, and since it does not
-                // fit anymore and it has been properly updated to contain
-                // the new data, forward it to the next level
-                lat = calculateAccessLatency(blk, pkt->headerDelay,
-                                             tag_latency);
                 invalidateBlock(blk);
                 return false;
             }
@@ -1267,9 +1235,6 @@ BaseCache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
 
         incHitCount(pkt);
 
-        // A writeback searches for the block, then writes the data
-        lat = calculateAccessLatency(blk, pkt->headerDelay, tag_latency);
-
         // When the packet metadata arrives, the tag lookup will be done while
         // the payload is arriving. Then the block will be ready to access as
         // soon as the fill is done
@@ -1284,12 +1249,12 @@ BaseCache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
         incHitCount(pkt);
 
         // Calculate access latency based on the need to access the data array
-        if (pkt->isRead() || pkt->isWrite()) {
+        if (pkt->isRead()) {
             lat = calculateAccessLatency(blk, pkt->headerDelay, tag_latency);
 
             // When a block is compressed, it must first be decompressed
             // before being read. This adds to the access latency.
-            if (compressor && pkt->isRead()) {
+            if (compressor) {
                 lat += compressor->getDecompressionLatency(blk);
             }
         } else {
index ddcf3ecb6f2ed8b0de56a967350f78a4e008f89f..dce0ce434570ad9f5cfc1c8b54736e4cf7433204 100644 (file)
@@ -274,6 +274,7 @@ class CacheBlk : public ReplaceableEntry
      */
     Tick getWhenReady() const
     {
+        assert(whenReady != MaxTick);
         return whenReady;
     }