From 273aacfe48e45bc3b73d91f5d4639ed8182fcb0c Mon Sep 17 00:00:00 2001 From: "Daniel R. Carvalho" Date: Tue, 19 Jun 2018 17:31:26 +0200 Subject: [PATCH] mem-cache: Add co-allocation function to compressed tags Implement a co-allocation function in compressed tags, so that compressed blocks can be co-allocated in a superblock. Co-allocation is possible when compression ratio (CR) blocks that share a superblock tag can be compressed to up to (100/CR)% of their size. Change-Id: I937cc1fcbb488e70309cb5478c12db65f1b4b23f Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/11411 Tested-by: kokoro Reviewed-by: Nikos Nikoleris Maintainer: Nikos Nikoleris --- src/mem/cache/tags/compressed_tags.cc | 75 +++++++++++++++++++++++++++ src/mem/cache/tags/compressed_tags.hh | 25 +++++++++ 2 files changed, 100 insertions(+) diff --git a/src/mem/cache/tags/compressed_tags.cc b/src/mem/cache/tags/compressed_tags.cc index 46043be68..94b929323 100644 --- a/src/mem/cache/tags/compressed_tags.cc +++ b/src/mem/cache/tags/compressed_tags.cc @@ -35,7 +35,10 @@ #include "mem/cache/tags/compressed_tags.hh" +#include "base/trace.hh" +#include "debug/CacheComp.hh" #include "mem/cache/replacement_policies/base.hh" +#include "mem/cache/replacement_policies/replaceable_entry.hh" #include "mem/cache/tags/indexing_policies/base.hh" #include "mem/packet.hh" #include "params/CompressedTags.hh" @@ -93,6 +96,78 @@ CompressedTags::tagsInit() } } +bool +CompressedTags::canCoAllocate(const SuperBlk* superblock, + const std::size_t compressed_size) const +{ + // Simple co-allocation function: at most numBlocksPerSector blocks that + // compress at least to (100/numBlocksPerSector)% of their original size + // can share a superblock + return superblock->isCompressed() && + (compressed_size <= (blkSize * 8) / numBlocksPerSector); +} + +CacheBlk* +CompressedTags::findVictim(Addr addr, const bool is_secure, + const std::size_t compressed_size, + std::vector& evict_blks) const +{ + // Get all possible locations of this superblock + const std::vector superblock_entries = + indexingPolicy->getPossibleEntries(addr); + + // Check if the superblock this address belongs to has been allocated. If + // so, try co-allocating + Addr tag = extractTag(addr); + SuperBlk* victim_superblock = nullptr; + bool is_co_allocation = false; + const uint64_t offset = extractSectorOffset(addr); + for (const auto& entry : superblock_entries){ + SuperBlk* superblock = static_cast(entry); + if ((tag == superblock->getTag()) && superblock->isValid() && + (is_secure == superblock->isSecure()) && + !superblock->blks[offset]->isValid() && + canCoAllocate(superblock, compressed_size)) + { + victim_superblock = superblock; + is_co_allocation = true; + break; + } + } + + // If the superblock is not present or cannot be co-allocated a + // superblock must be replaced + if (victim_superblock == nullptr){ + // Choose replacement victim from replacement candidates + victim_superblock = static_cast( + replacementPolicy->getVictim(superblock_entries)); + + // The whole superblock must be evicted to make room for the new one + for (const auto& blk : victim_superblock->blks){ + evict_blks.push_back(blk); + } + } + + // Get the location of the victim block within the superblock + SectorSubBlk* victim = victim_superblock->blks[offset]; + + // It would be a hit if victim was valid in a co-allocation, and upgrades + // do not call findVictim, so it cannot happen + if (is_co_allocation){ + assert(!victim->isValid()); + + // Print all co-allocated blocks + DPRINTF(CacheComp, "Co-Allocation: offset %d with blocks\n", offset); + for (const auto& blk : victim_superblock->blks){ + if (blk->isValid()) { + DPRINTFR(CacheComp, "\t[%s]\n", blk->print()); + } + } + } + + return victim; +} + void CompressedTags::insertBlock(const PacketPtr pkt, CacheBlk *blk) { diff --git a/src/mem/cache/tags/compressed_tags.hh b/src/mem/cache/tags/compressed_tags.hh index 303bc79d8..f9321b946 100644 --- a/src/mem/cache/tags/compressed_tags.hh +++ b/src/mem/cache/tags/compressed_tags.hh @@ -42,6 +42,7 @@ #include "mem/cache/tags/super_blk.hh" class BaseCache; +class CacheBlk; struct CompressedTagsParams; /** @@ -96,6 +97,30 @@ class CompressedTags : public SectorTags */ void tagsInit() override; + /** + * Checks whether a superblock can co-allocate given compressed data block. + * + * @param superblock Superblock to check. + * @param compressed_size Size, in bits, of new block to allocate. + * @return True if block can be co-allocated in superblock. + */ + bool canCoAllocate(const SuperBlk* superblock, + const std::size_t compressed_size) const; + + /** + * Find replacement victim based on address. Checks if data can be co- + * allocated before choosing blocks to be evicted. + * + * @param addr Address to find a victim for. + * @param is_secure True if the target memory space is secure. + * @param compressed_size Size, in bits, of new block to allocate. + * @param evict_blks Cache blocks to be evicted. + * @return Cache block to be replaced. + */ + CacheBlk* findVictim(Addr addr, const bool is_secure, + const std::size_t compressed_size, + std::vector& evict_blks) const override; + /** * Insert the new block into the cache and update replacement data. * -- 2.30.2