X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=inline;f=src%2Fmem%2Fcache%2Ftags%2Fcompressed_tags.cc;h=64a7102d1874c2b7284f53e58d468f4411d68059;hb=91d83cc8a12883f2d7493b37f50487cd7f03a9e6;hp=cc799df24fa208a88d01ac50c337146921f1c8bb;hpb=e22a6c9180da43364692217ea257ff754dd5df45;p=gem5.git diff --git a/src/mem/cache/tags/compressed_tags.cc b/src/mem/cache/tags/compressed_tags.cc index cc799df24..64a7102d1 100644 --- a/src/mem/cache/tags/compressed_tags.cc +++ b/src/mem/cache/tags/compressed_tags.cc @@ -24,8 +24,6 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Daniel Carvalho */ /** @@ -35,11 +33,15 @@ #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" -CompressedTags::CompressedTags(const Params *p) +CompressedTags::CompressedTags(const Params &p) : SectorTags(p) { } @@ -59,8 +61,9 @@ CompressedTags::tagsInit() // Locate next cache superblock SuperBlk* superblock = &superBlks[superblock_index]; - // Link block to indexing policy - indexingPolicy->setEntry(superblock, superblock_index); + // Superblocks must be aware of the block size due to their co- + // allocation conditions + superblock->setBlkSize(blkSize); // Associate a replacement data entry to the block superblock->replacementData = replacementPolicy->instantiateEntry(); @@ -89,6 +92,97 @@ CompressedTags::tagsInit() // Update block index ++blk_index; } + + // Link block to indexing policy + indexingPolicy->setEntry(superblock, superblock_index); + } +} + +CacheBlk* +CompressedTags::findVictim(Addr addr, const bool is_secure, + const std::size_t compressed_size, + std::vector& evict_blks) +{ + // 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 (superblock->matchTag(tag, is_secure) && + !superblock->blks[offset]->isValid() && + superblock->isCompressed() && + superblock->canCoAllocate(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){ + if (blk->isValid()) { + 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()); + } + } + } + + // Update number of sub-blocks evicted due to a replacement + sectorStats.evictionsReplacement[evict_blks.size()]++; + + return victim; +} + +void +CompressedTags::insertBlock(const PacketPtr pkt, CacheBlk *blk) +{ + // We check if block can co-allocate before inserting, because this check + // assumes the block is still invalid + CompressionBlk* compression_blk = static_cast(blk); + const SuperBlk* superblock = static_cast( + compression_blk->getSectorBlock()); + const bool is_co_allocatable = superblock->isCompressed() && + superblock->canCoAllocate(compression_blk->getSizeBits()); + + // Insert block + SectorTags::insertBlock(pkt, blk); + + // We always store compressed blocks when possible + if (is_co_allocatable) { + compression_blk->setCompressed(); + } else { + compression_blk->setUncompressed(); } } @@ -112,7 +206,7 @@ CompressedTags::anyBlk(std::function visitor) } CompressedTags * -CompressedTagsParams::create() +CompressedTagsParams::create() const { - return new CompressedTags(this); + return new CompressedTags(*this); }