From: Daniel R. Carvalho Date: Mon, 16 Sep 2019 14:22:55 +0000 (+0200) Subject: mem-cache: Add a masked pattern to compressors X-Git-Tag: v19.0.0.0~380 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=83219d89de2f55fc40b3744115ad1fab94e85ef3;p=gem5.git mem-cache: Add a masked pattern to compressors 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 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/21150 Reviewed-by: Nikos Nikoleris Maintainer: Nikos Nikoleris Tested-by: kokoro --- diff --git a/src/mem/cache/compressors/cpack.hh b/src/mem/cache/compressors/cpack.hh index 3ecab5028..7b10ac3e7 100644 --- a/src/mem/cache/compressors/cpack.hh +++ b/src/mem/cache/compressors/cpack.hh @@ -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]}; } }; diff --git a/src/mem/cache/compressors/dictionary_compressor.hh b/src/mem/cache/compressors/dictionary_compressor.hh index 9e0e4df80..3c828f040 100644 --- a/src/mem/cache/compressors/dictionary_compressor.hh +++ b/src/mem/cache/compressors/dictionary_compressor.hh @@ -111,6 +111,9 @@ template class DictionaryCompressor : public BaseDictionaryCompressor { protected: + /** Convenience typedef for a dictionary entry. */ + typedef std::array 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 DictionaryEntry; + template + class MaskedPattern; /** * Create a factory to determine if input matches a pattern. The if else @@ -420,4 +422,62 @@ class DictionaryCompressor::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 +template +class DictionaryCompressor::MaskedPattern + : public DictionaryCompressor::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::Pattern(number, code, metadata_length, + popCount(~mask) / 8, match_location, allocate), + bits(DictionaryCompressor::fromDictionaryEntry(bytes) & ~mask) + { + } + + static bool + isPattern(const DictionaryEntry& bytes, const DictionaryEntry& dict_bytes, + const int match_location) + { + const T masked_bytes = + DictionaryCompressor::fromDictionaryEntry(bytes) & mask; + const T masked_dict_bytes = + DictionaryCompressor::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::fromDictionaryEntry(dict_bytes) & mask; + return DictionaryCompressor::toDictionaryEntry( + bits | masked_dict_bytes); + } +}; + #endif //__MEM_CACHE_COMPRESSORS_DICTIONARY_COMPRESSOR_HH__