mem-cache: Prune unnecessary writebacks in exclusive caches
authorNikos Nikoleris <nikos.nikoleris@arm.com>
Mon, 4 Sep 2017 15:38:36 +0000 (16:38 +0100)
committerNikos Nikoleris <nikos.nikoleris@arm.com>
Tue, 9 Jan 2018 17:04:32 +0000 (17:04 +0000)
Exclusive caches use the tempBlock to fill for responses from a
downstream cache. The reason for this is that they only pass the block
to the cache above without keeping a copy. When all requests are
serviced the block is immediately invalidated unless it is dirty, in
which case it has to be written back to the memory below.

To avoid unnecessary writebacks, this changeset forces mostly
exclusive caches to issuse requests that can only fetch clean data
when possible.

Reported-by: Quereshi Muhammad Avais <avais@kaist.ac.kr>
Change-Id: I01b377563f5aa3e12d22f425a04db7c023071849
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/5061
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>

src/mem/cache/cache.cc

index a83f8ab12d5d1c59899993a71873f99a868538d0..421fa5b72cc5f2730c650d2c2d2e6aaf24fc2c5a 100644 (file)
@@ -1021,8 +1021,18 @@ Cache::createMissPacket(PacketPtr cpu_pkt, CacheBlk *blk,
         cmd = MemCmd::SCUpgradeFailReq;
     } else {
         // block is invalid
+
+        // If the request does not need a writable there are two cases
+        // where we need to ensure the response will not fetch the
+        // block in dirty state:
+        // * this cache is read only and it does not perform
+        //   writebacks,
+        // * this cache is mostly exclusive and will not fill (since
+        //   it does not fill it will have to writeback the dirty data
+        //   immediately which generates uneccesary writebacks).
+        bool force_clean_rsp = isReadOnly || clusivity == Enums::mostly_excl;
         cmd = needsWritable ? MemCmd::ReadExReq :
-            (isReadOnly ? MemCmd::ReadCleanReq : MemCmd::ReadSharedReq);
+            (force_clean_rsp ? MemCmd::ReadCleanReq : MemCmd::ReadSharedReq);
     }
     PacketPtr pkt = new Packet(cpu_pkt->req, cmd, blkSize);