mem-cache: Add data expansion and compaction checking functions
authorDaniel R. Carvalho <odanrc@yahoo.com.br>
Wed, 19 Jun 2019 14:07:43 +0000 (16:07 +0200)
committerDaniel Carvalho <odanrc@yahoo.com.br>
Thu, 12 Nov 2020 21:46:43 +0000 (21:46 +0000)
Data expansion and compaction are determined according to the compaction
method being used. Therefore, do the verification on the blocks instead
of the cache.

Change-Id: I652418a5f4c6d5b946a9925d6287a995f262f02a
Signed-off-by: Daniel R. Carvalho <odanrc@yahoo.com.br>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/36579
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/mem/cache/base.cc
src/mem/cache/tags/super_blk.cc
src/mem/cache/tags/super_blk.hh

index 78e3f3e360ff35c72ef24c2fbce7f14835d1555e..09c810a7e71aa466391eca20a7075bd26f677b31 100644 (file)
@@ -849,10 +849,6 @@ BaseCache::updateCompressionData(CacheBlk *&blk, const uint64_t* data,
         compressor->compress(data, compression_lat, decompression_lat);
     std::size_t compression_size = comp_data->getSizeBits();
 
-    // If block's compression factor increased, it may not be co-allocatable
-    // anymore. If so, some blocks might need to be evicted to make room for
-    // the bigger block
-
     // Get previous compressed size
     CompressionBlk* compression_blk = static_cast<CompressionBlk*>(blk);
     M5_VAR_USED const std::size_t prev_size = compression_blk->getSizeBits();
@@ -867,16 +863,18 @@ BaseCache::updateCompressionData(CacheBlk *&blk, const uint64_t* data,
     // 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;
+    const CompressionBlk::OverwriteType overwrite_type =
+        compression_blk->checkExpansionContraction(compression_size);
     string op_name = "";
-    if (was_compressed && !is_co_allocatable) {
-        is_data_expansion = true;
+    if (overwrite_type == CompressionBlk::DATA_EXPANSION) {
         op_name = "expansion";
-    } else if (moveContractions && !was_compressed && is_co_allocatable) {
-        is_data_contraction = true;
+        is_data_expansion = true;
+    } else if ((overwrite_type == CompressionBlk::DATA_CONTRACTION) &&
+        moveContractions) {
         op_name = "contraction";
+        is_data_contraction = true;
     }
 
     // If block changed compression state, it was possibly co-allocated with
index a6d8afb8162417be9507df5d0984311d9916a7af..9f7ce6552b827057194e48b7ac038b1577cb81c2 100644 (file)
@@ -114,6 +114,21 @@ CompressionBlk::invalidate()
     setUncompressed();
 }
 
+CompressionBlk::OverwriteType
+CompressionBlk::checkExpansionContraction(const std::size_t size) const
+{
+    // @todo As of now only two states are supported: compressed to its
+    // maximum compression, and uncompressed. Support for intermediate
+    // states (e.g., if MaxCR=4, 2/4 and 3/4 of the blkSize) should be added
+    const SuperBlk* superblock =
+        static_cast<const SuperBlk*>(getSectorBlock());
+    const bool prev_compressed = isCompressed();
+    const bool new_compressed = superblock->canCoAllocate(size);
+    return (prev_compressed == new_compressed) ? UNCHANGED :
+        ((prev_compressed & !new_compressed) ? DATA_EXPANSION :
+        DATA_CONTRACTION);
+}
+
 std::string
 CompressionBlk::print() const
 {
index d7abe18723a75479045e8079fefef43bee714959..354b3f5400ef0aa97923f66a5cc0c6042e04908f 100644 (file)
@@ -63,6 +63,21 @@ class CompressionBlk : public SectorSubBlk
     bool _compressed;
 
   public:
+    /**
+     * When an overwrite happens, the data size may change an not fit in its
+     * current container any longer. This enum declared which kind of size
+     * change happened in this situation.
+     */
+    enum OverwriteType : int
+    {
+        /** New data contents are considered smaller than previous contents. */
+        DATA_CONTRACTION = -1,
+        /** New and old contents are considered of similar sizes. */
+        UNCHANGED = 0,
+        /** New data contents are considered larger than previous contents. */
+        DATA_EXPANSION = 1,
+    };
+
     CompressionBlk();
     CompressionBlk(const CompressionBlk&) = delete;
     CompressionBlk& operator=(const CompressionBlk&) = delete;
@@ -125,6 +140,18 @@ class CompressionBlk : public SectorSubBlk
 
     void invalidate() override;
 
+    /**
+     * Determines if changing the size of the block will cause a data
+     * expansion (new size is bigger) or contraction (new size is smaller).
+     * Sizes are not necessarily compared at at bit granularities (e.g., 20
+     * bits is considered equal to 23 bits when blocks use 32-bit spaces as
+     * minimum allocation units).
+     *
+     * @param size The new compressed size.
+     * @return Type of size change. @sa OverwriteType.
+     */
+    OverwriteType checkExpansionContraction(const std::size_t size) const;
+
     /**
      * Pretty-print sector offset and other CacheBlk information.
      *