diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc index 78e3f3e360..09c810a7e7 100644 --- a/src/mem/cache/base.cc +++ b/src/mem/cache/base.cc @@ -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(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 diff --git a/src/mem/cache/tags/super_blk.cc b/src/mem/cache/tags/super_blk.cc index a6d8afb816..9f7ce6552b 100644 --- a/src/mem/cache/tags/super_blk.cc +++ b/src/mem/cache/tags/super_blk.cc @@ -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(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 { diff --git a/src/mem/cache/tags/super_blk.hh b/src/mem/cache/tags/super_blk.hh index d7abe18723..354b3f5400 100644 --- a/src/mem/cache/tags/super_blk.hh +++ b/src/mem/cache/tags/super_blk.hh @@ -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. *