summaryrefslogtreecommitdiff
path: root/src/mem/cache
diff options
context:
space:
mode:
authorDaniel R. Carvalho <odanrc@yahoo.com.br>2018-06-19 17:31:26 +0200
committerDaniel Carvalho <odanrc@yahoo.com.br>2019-05-08 17:41:09 +0000
commit273aacfe48e45bc3b73d91f5d4639ed8182fcb0c (patch)
treee3d5bac6bb758fb79e49b8db9f201b49428c90c1 /src/mem/cache
parenta39af1f0ac6d324b4c206d4db18c39ea557bb931 (diff)
downloadgem5-273aacfe48e45bc3b73d91f5d4639ed8182fcb0c.tar.xz
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 <noreply+kokoro@google.com> Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com> Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>
Diffstat (limited to 'src/mem/cache')
-rw-r--r--src/mem/cache/tags/compressed_tags.cc75
-rw-r--r--src/mem/cache/tags/compressed_tags.hh25
2 files changed, 100 insertions, 0 deletions
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<CacheBlk*>& evict_blks) const
+{
+ // Get all possible locations of this superblock
+ const std::vector<ReplaceableEntry*> 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<SuperBlk*>(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<SuperBlk*>(
+ 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;
/**
@@ -97,6 +98,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<CacheBlk*>& evict_blks) const override;
+
+ /**
* Insert the new block into the cache and update replacement data.
*
* @param pkt Packet holding the address to update