Daniel Carvalho has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/36578 )

Change subject: mem-cache: Allow moving data contractions
......................................................................

mem-cache: Allow moving data contractions

Data contractions happen when a block passes from a less compressed
(e.g., uncompressed) to a more compressed (e.g., compressed) state.

Some compaction methods enforce that a block can only be allocated
in a location matches an exact compression factor, thus on data
contractions such blocks must be moved to another location, or
they must be padded to fake a bigger size.

For compaction methods that do not have that limitation, performance
can be improved if the contracted block is moved to co-allocate with
another existing entry, since it frees up an entry.

Change-Id: I302bc561b897f9d3ce1426331fe4b5c2df76f4b5
Signed-off-by: Daniel R. Carvalho <[email protected]>
---
M src/mem/cache/Cache.py
M src/mem/cache/base.cc
M src/mem/cache/base.hh
3 files changed, 64 insertions(+), 16 deletions(-)



diff --git a/src/mem/cache/Cache.py b/src/mem/cache/Cache.py
index 149f485..a99d549 100644
--- a/src/mem/cache/Cache.py
+++ b/src/mem/cache/Cache.py
@@ -105,6 +105,11 @@
     compressor = Param.BaseCacheCompressor(NULL, "Cache compressor.")
     replace_expansions = Param.Bool(True, "Apply replacement policy to " \
         "decide which blocks should be evicted on a data expansion")
+    # When a block passes from uncompressed to compressed, it may become
+    # co-allocatable with another existing entry of the same superblock,
+    # so try move the block to co-allocate it
+    move_contractions = Param.Bool(True, "Try to co-allocate blocks that "
+        "contract")

     sequential_access = Param.Bool(False,
         "Whether to access tags and data sequentially")
diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc
index c296822..39f06b8 100644
--- a/src/mem/cache/base.cc
+++ b/src/mem/cache/base.cc
@@ -100,6 +100,7 @@
       clusivity(p.clusivity),
       isReadOnly(p.is_read_only),
       replaceExpansions(p.replace_expansions),
+      moveContractions(p.move_contractions),
       blocked(0),
       order(0),
       noTargetMSHR(nullptr),
@@ -862,15 +863,31 @@
const bool is_co_allocatable = superblock->isCompressed(compression_blk) &&
         superblock->canCoAllocate(compression_size);

- // If block was compressed, possibly co-allocated with other blocks, and - // cannot be co-allocated anymore, one or more blocks must be evicted to
-    // make room for the expanded block
+ // If compressed size didn't change enough to modify its co-allocatability
+    // there is nothing to do. Otherwise we may be facing a data expansion
+    // (block passing from more compressed to less compressed state), or a
+    // data contraction (less to more).
     const bool was_compressed = compression_blk->isCompressed();
+    bool is_data_expansion = false;
+    bool is_data_contraction = false;
+    string op_name = "";
     if (was_compressed && !is_co_allocatable) {
+        is_data_expansion = true;
+        op_name = "expansion";
+    } else if (moveContractions && !was_compressed && is_co_allocatable) {
+        is_data_contraction = true;
+        op_name = "contraction";
+    }
+
+ // If block changed compression state, it was possibly co-allocated with + // other blocks and cannot be co-allocated anymore, so one or more blocks
+    // must be evicted to make room for the expanded/contracted block
+    std::vector<CacheBlk*> evict_blks;
+    if (is_data_expansion || is_data_contraction) {
         std::vector<CacheBlk*> evict_blks;
         bool victim_itself = false;
         CacheBlk *victim = nullptr;
-        if (replaceExpansions) {
+        if (replaceExpansions || is_data_contraction) {
             victim = tags->findVictim(regenerateBlkAddr(blk),
                 blk->isSecure(), compression_size, evict_blks);

@@ -889,8 +906,8 @@
             }

             // Print victim block's information
-            DPRINTF(CacheRepl, "Data expansion replacement victim: %s\n",
-                victim->print());
+            DPRINTF(CacheRepl, "Data %s replacement victim: %s\n",
+                op_name, victim->print());
         } else {
             // If we do not move the expanded block, we must make room for
             // the expansion to happen, so evict every co-allocated block
@@ -908,12 +925,10 @@
             return false;
         }

-        // Update the number of data expansions
-        stats.dataExpansions++;
- DPRINTF(CacheComp, "Data expansion: expanding [%s] from %d to %d bits"
-                "\n", blk->print(), prev_size, compression_size);
+        DPRINTF(CacheComp, "Data %s: [%s] from %d to %d bits\n",
+                op_name, blk->print(), prev_size, compression_size);

-        if (!victim_itself && replaceExpansions) {
+        if (!victim_itself && (replaceExpansions || is_data_contraction)) {
// Move the block's contents to the invalid block so that it now
             // co-allocates with the other existing superblock entry
             tags->moveBlock(blk, victim);
@@ -922,15 +937,27 @@
         }
     }

-    // We always store compressed blocks when possible
-    if (is_co_allocatable) {
-        compression_blk->setCompressed();
-    } else {
-        compression_blk->setUncompressed();
+    // Update the number of data expansions/contractions
+    if (is_data_expansion) {
+        stats.dataExpansions++;
+    } else if (is_data_contraction) {
+        stats.dataContractions++;
     }
+
     compression_blk->setSizeBits(compression_size);
     compression_blk->setDecompressionLatency(decompression_lat);

+    if (is_data_expansion || is_data_contraction) {
+        // If contracting data, for sure data is compressed. If expanding,
+ // both situations can arise. When no contraction or expansion happens
+        // block keeps its old state
+        if (is_co_allocatable) {
+            compression_blk->setCompressed();
+        } else {
+            compression_blk->setUncompressed();
+        }
+    }
+
     return true;
 }

@@ -2088,6 +2115,7 @@
     replacements(this, "replacements", "number of replacements"),

     dataExpansions(this, "data_expansions", "number of data expansions"),
+ dataContractions(this, "data_contractions", "number of data contractions"),
     cmd(MemCmd::NUM_MEM_CMDS)
 {
     for (int idx = 0; idx < MemCmd::NUM_MEM_CMDS; ++idx)
@@ -2307,6 +2335,7 @@
     }

     dataExpansions.flags(nozero | nonan);
+    dataContractions.flags(nozero | nonan);
 }

 void
diff --git a/src/mem/cache/base.hh b/src/mem/cache/base.hh
index 62c2953..8dad1b7 100644
--- a/src/mem/cache/base.hh
+++ b/src/mem/cache/base.hh
@@ -902,6 +902,14 @@
     const bool replaceExpansions;

     /**
+     * Similar to data expansions, after a block improves its compression,
+ * it may need to be moved elsewhere compatible with the new compression + * factor, or, if not required by the compaction method, it may be moved
+     * to co-allocate with an existing block and thus free an entry.
+     */
+    const bool moveContractions;
+
+    /**
      * Bit vector of the blocking reasons for the access path.
      * @sa #BlockedCause
      */
@@ -1074,6 +1082,12 @@
         /** Number of data expansions. */
         Stats::Scalar dataExpansions;

+        /**
+         * Number of data contractions (blocks that had their compression
+         * factor improved).
+         */
+        Stats::Scalar dataContractions;
+
         /** Per-command statistics */
         std::vector<std::unique_ptr<CacheCmdStats>> cmd;
     } stats;

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/36578
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I302bc561b897f9d3ce1426331fe4b5c2df76f4b5
Gerrit-Change-Number: 36578
Gerrit-PatchSet: 1
Gerrit-Owner: Daniel Carvalho <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to