mem-cache: Add a repeated value pattern to compressors
authorDaniel R. Carvalho <odanrc@yahoo.com.br>
Tue, 17 Sep 2019 09:45:01 +0000 (11:45 +0200)
committerDaniel Carvalho <odanrc@yahoo.com.br>
Tue, 29 Oct 2019 21:32:02 +0000 (21:32 +0000)
The repeated value pattern checks if values are composed of multiple
instances of the same value. If successful, the bits of the repeated
value are included only once in the compressed data.

Change-Id: Ia7045b4e33a91fd8d712fe1ca689f7f8cb4e5feb
Signed-off-by: Daniel R. Carvalho <odanrc@yahoo.com.br>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/21153
Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu>
Maintainer: Jason Lowe-Power <jason@lowepower.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/mem/cache/compressors/dictionary_compressor.hh

index 6922715fdc230125a9e3545a10351b6428e3c917..cf44a321d8fce76b285527318ed6ce7d5e9da6ec 100644 (file)
@@ -127,6 +127,8 @@ class DictionaryCompressor : public BaseDictionaryCompressor
     class MaskedPattern;
     template <T value, T mask>
     class MaskedValuePattern;
+    template <class RepT>
+    class RepeatedValuePattern;
 
     /**
      * Create a factory to determine if input matches a pattern. The if else
@@ -538,4 +540,72 @@ class DictionaryCompressor<T>::MaskedValuePattern
     }
 };
 
+/**
+ * A pattern that checks if dictionary entry sized values are solely composed
+ * of multiple copies of a single value.
+ *
+ * For example, if we are looking for repeated bytes in a 1-byte granularity
+ * (RepT is uint8_t), the value 0x3232 would match, however 0x3332 wouldn't.
+ *
+ * @tparam RepT The type of the repeated value, which must fit in a dictionary
+ *              entry.
+ */
+template <class T>
+template <class RepT>
+class DictionaryCompressor<T>::RepeatedValuePattern
+    : public DictionaryCompressor<T>::Pattern
+{
+  private:
+    static_assert(sizeof(T) > sizeof(RepT), "The repeated value's type must "
+        "be smaller than the dictionary entry's type.");
+
+    /** The repeated value. */
+    RepT value;
+
+  public:
+    RepeatedValuePattern(const int number,
+        const uint64_t code,
+        const uint64_t metadata_length,
+        const int match_location,
+        const DictionaryEntry bytes,
+        const bool allocate = true)
+      : DictionaryCompressor<T>::Pattern(number, code, metadata_length,
+            8 * sizeof(RepT), match_location, allocate),
+        value(DictionaryCompressor<T>::fromDictionaryEntry(bytes))
+    {
+    }
+
+    static bool
+    isPattern(const DictionaryEntry& bytes, const DictionaryEntry& dict_bytes,
+        const int match_location)
+    {
+        // Parse the dictionary entry in a RepT granularity, and if all values
+        // are equal, this is a repeated value pattern. Since the dictionary
+        // is not being used, the match_location is irrelevant
+        T bytes_value = DictionaryCompressor<T>::fromDictionaryEntry(bytes);
+        const RepT rep_value = bytes_value;
+        for (int i = 0; i < (sizeof(T) / sizeof(RepT)); i++) {
+            RepT cur_value = bytes_value;
+            if (cur_value != rep_value) {
+                return false;
+            }
+            bytes_value >>= 8 * sizeof(RepT);
+        }
+        return true;
+    }
+
+    DictionaryEntry
+    decompress(const DictionaryEntry dict_bytes) const override
+    {
+        // The decompressed value is just multiple consecutive instances of
+        // the same value
+        T decomp_value = 0;
+        for (int i = 0; i < (sizeof(T) / sizeof(RepT)); i++) {
+            decomp_value <<= 8 * sizeof(RepT);
+            decomp_value |= value;
+        }
+        return DictionaryCompressor<T>::toDictionaryEntry(decomp_value);
+    }
+};
+
 #endif //__MEM_CACHE_COMPRESSORS_DICTIONARY_COMPRESSOR_HH__