* 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
*/
/**
#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)
{
}
// 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();
// 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<CacheBlk*>& evict_blks)
+{
+ // 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 (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<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){
+ 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<CompressionBlk*>(blk);
+ const SuperBlk* superblock = static_cast<const SuperBlk*>(
+ 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();
}
}
}
CompressedTags *
-CompressedTagsParams::create()
+CompressedTagsParams::create() const
{
- return new CompressedTags(this);
+ return new CompressedTags(*this);
}