mem-cache: Add a masked pattern to compressors
authorDaniel R. Carvalho <odanrc@yahoo.com.br>
Mon, 16 Sep 2019 14:22:55 +0000 (16:22 +0200)
committerDaniel Carvalho <odanrc@yahoo.com.br>
Tue, 29 Oct 2019 21:32:02 +0000 (21:32 +0000)
The masked pattern compares masked values to masked dictionary entries
to determine whether these values match. If successful, the bits that
do not match must be added to the compressed data.

Change-Id: I4b1c8feb0faa99576382b54a73a20c353f965d2a
Signed-off-by: Daniel R. Carvalho <odanrc@yahoo.com.br>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/21150
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/compressors/cpack.hh
src/mem/cache/compressors/dictionary_compressor.hh

index 3ecab5028144b285398987aeb64ca41807a4f5ec..7b10ac3e70bad76f9323bd6b5eb489b13ab2d6e7 100644 (file)
@@ -154,55 +154,21 @@ class CPack::PatternXXXX : public UncompressedPattern
     }
 };
 
-class CPack::PatternMMMM : public DictionaryCompressor::Pattern
+class CPack::PatternMMMM : public MaskedPattern<0xFFFFFFFF>
 {
   public:
     PatternMMMM(const DictionaryEntry bytes, const int match_location)
-        : Pattern(MMMM, 0x2, 6, 0, match_location, true) {}
-
-    static bool isPattern(const DictionaryEntry& bytes,
-        const DictionaryEntry& dict_bytes,
-        const int match_location)
-    {
-        return (bytes == dict_bytes) && (match_location >= 0);
-    }
-
-    DictionaryEntry
-    decompress(const DictionaryEntry dict_bytes) const override
+        : MaskedPattern<0xFFFFFFFF>(MMMM, 0x2, 6, match_location, bytes, true)
     {
-        return dict_bytes;
     }
 };
 
-class CPack::PatternMMXX : public DictionaryCompressor::Pattern
+class CPack::PatternMMXX : public MaskedPattern<0xFFFF0000>
 {
-  private:
-    /**
-     * A copy of the unmatched bytes.
-     */
-    const uint8_t byte0;
-    const uint8_t byte1;
-
   public:
     PatternMMXX(const DictionaryEntry bytes, const int match_location)
-        : Pattern(MMXX, 0xC, 8, 2, match_location, true),
-                  byte0(bytes[0]), byte1(bytes[1]) {}
-
-    static bool isPattern(const DictionaryEntry& bytes,
-        const DictionaryEntry& dict_bytes,
-        const int match_location)
-    {
-        // Notice we don't compare bytes[0], as otherwise we'd be unnecessarily
-        // discarding MMXM. If that pattern is added this should be modified
-        return (bytes[3] == dict_bytes[3]) && (bytes[2] == dict_bytes[2]) &&
-               (bytes[1] != dict_bytes[1]) && (match_location >= 0);
-
-    }
-
-    DictionaryEntry
-    decompress(const DictionaryEntry dict_bytes) const override
+        : MaskedPattern<0xFFFF0000>(MMXX, 0xC, 8, match_location, bytes, true)
     {
-        return {byte0, byte1, dict_bytes[2], dict_bytes[3]};
     }
 };
 
@@ -233,32 +199,12 @@ class CPack::PatternZZZX : public DictionaryCompressor::Pattern
     }
 };
 
-class CPack::PatternMMMX : public DictionaryCompressor::Pattern
+class CPack::PatternMMMX : public MaskedPattern<0xFFFFFF00>
 {
-  private:
-    /**
-     * A copy of the unmatched byte.
-     */
-    const uint8_t byte;
-
   public:
     PatternMMMX(const DictionaryEntry bytes, const int match_location)
-        : Pattern(MMMX, 0xE, 8, 1, match_location, true),
-                  byte(bytes[0]) {}
-
-    static bool isPattern(const DictionaryEntry& bytes,
-        const DictionaryEntry& dict_bytes,
-        const int match_location)
-    {
-        return (bytes[3] == dict_bytes[3]) && (bytes[2] == dict_bytes[2]) &&
-               (bytes[1] == dict_bytes[1]) && (bytes[0] != dict_bytes[0]) &&
-               (match_location >= 0);
-    }
-
-    DictionaryEntry
-    decompress(const DictionaryEntry dict_bytes) const override
+        : MaskedPattern<0xFFFFFF00>(MMMX, 0xE, 8, match_location, bytes, true)
     {
-        return {byte, dict_bytes[1], dict_bytes[2], dict_bytes[3]};
     }
 };
 
index 9e0e4df804b5dacca98ddd2658fe8d29c8ddfb31..3c828f040f64ee7616e543ad733c3f34ec2ee275 100644 (file)
@@ -111,6 +111,9 @@ template <class T>
 class DictionaryCompressor : public BaseDictionaryCompressor
 {
   protected:
+    /** Convenience typedef for a dictionary entry. */
+    typedef std::array<uint8_t, sizeof(T)> DictionaryEntry;
+
     /**
      * Compression data for the dictionary compressor. It consists of a vector
      * of patterns.
@@ -120,9 +123,8 @@ class DictionaryCompressor : public BaseDictionaryCompressor
     // Forward declaration of a pattern
     class Pattern;
     class UncompressedPattern;
-
-    /** Convenience typedef for a dictionary entry. */
-    typedef std::array<uint8_t, sizeof(T)> DictionaryEntry;
+    template <T mask>
+    class MaskedPattern;
 
     /**
      * Create a factory to determine if input matches a pattern. The if else
@@ -420,4 +422,62 @@ class DictionaryCompressor<T>::UncompressedPattern
     }
 };
 
+/**
+ * A pattern that compares masked values against dictionary entries. If
+ * the masked dictionary entry matches perfectly the masked value to be
+ * compressed, there is a pattern match.
+ *
+ * For example, if the mask is 0xFF00 (that is, this pattern matches the MSB),
+ * the value (V) 0xFF20 is being compressed, and the dictionary contains
+ * the value (D) 0xFF03, this is a match (V & mask == 0xFF00 == D & mask),
+ * and 0x0020 is added to the list of unmatched bits.
+ *
+ * @tparam mask A mask containing the bits that must match.
+ */
+template <class T>
+template <T mask>
+class DictionaryCompressor<T>::MaskedPattern
+    : public DictionaryCompressor<T>::Pattern
+{
+  private:
+    static_assert(mask != 0, "The pattern's value mask must not be zero. Use "
+        "the uncompressed pattern instead.");
+
+    /** A copy of the bits that do not belong to the mask. */
+    const T bits;
+
+  public:
+    MaskedPattern(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,
+            popCount(~mask) / 8, match_location, allocate),
+        bits(DictionaryCompressor<T>::fromDictionaryEntry(bytes) & ~mask)
+    {
+    }
+
+    static bool
+    isPattern(const DictionaryEntry& bytes, const DictionaryEntry& dict_bytes,
+        const int match_location)
+    {
+        const T masked_bytes =
+            DictionaryCompressor<T>::fromDictionaryEntry(bytes) & mask;
+        const T masked_dict_bytes =
+            DictionaryCompressor<T>::fromDictionaryEntry(dict_bytes) & mask;
+        return (match_location >= 0) && (masked_bytes == masked_dict_bytes);
+    }
+
+    DictionaryEntry
+    decompress(const DictionaryEntry dict_bytes) const override
+    {
+        const T masked_dict_bytes =
+            DictionaryCompressor<T>::fromDictionaryEntry(dict_bytes) & mask;
+        return DictionaryCompressor<T>::toDictionaryEntry(
+            bits | masked_dict_bytes);
+    }
+};
+
 #endif //__MEM_CACHE_COMPRESSORS_DICTIONARY_COMPRESSOR_HH__