From 248c8d36ecef89f1bd63593398e087b02b5f33e8 Mon Sep 17 00:00:00 2001 From: "Daniel R. Carvalho" Date: Tue, 17 Sep 2019 11:45:01 +0200 Subject: [PATCH] mem-cache: Add a repeated value pattern to compressors 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 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/21153 Reviewed-by: Bobby R. Bruce Maintainer: Jason Lowe-Power Tested-by: kokoro --- .../compressors/dictionary_compressor.hh | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/src/mem/cache/compressors/dictionary_compressor.hh b/src/mem/cache/compressors/dictionary_compressor.hh index 6922715fd..cf44a321d 100644 --- a/src/mem/cache/compressors/dictionary_compressor.hh +++ b/src/mem/cache/compressors/dictionary_compressor.hh @@ -127,6 +127,8 @@ class DictionaryCompressor : public BaseDictionaryCompressor class MaskedPattern; template class MaskedValuePattern; + template + class RepeatedValuePattern; /** * Create a factory to determine if input matches a pattern. The if else @@ -538,4 +540,72 @@ class DictionaryCompressor::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 +template +class DictionaryCompressor::RepeatedValuePattern + : public DictionaryCompressor::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::Pattern(number, code, metadata_length, + 8 * sizeof(RepT), match_location, allocate), + value(DictionaryCompressor::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::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::toDictionaryEntry(decomp_value); + } +}; + #endif //__MEM_CACHE_COMPRESSORS_DICTIONARY_COMPRESSOR_HH__ -- 2.30.2