#include <cassert>
#include <cstring>
-#include <memory>
#include <vector>
+#include "debug/CacheRepl.hh"
#include "mem/cache/base.hh"
#include "mem/cache/blk.hh"
+#include "mem/cache/replacement_policies/base.hh"
#include "mem/cache/tags/base.hh"
#include "mem/cache/tags/cacheset.hh"
#include "mem/packet.hh"
BaseReplacementPolicy *replacementPolicy;
public:
-
/** Convenience typedef. */
typedef BaseSetAssocParams Params;
*/
virtual ~BaseSetAssoc() {};
+ /**
+ * This function updates the tags when a block is invalidated but does
+ * not invalidate the block itself. It also updates the replacement data.
+ *
+ * @param blk The block to invalidate.
+ */
+ void invalidate(CacheBlk *blk) override;
+
/**
* Find the cache block given set and way
* @param set The set of the block.
accessLatency;
}
+ // Update number of references to accessed block
+ blk->refCount++;
+
// Update replacement data of accessed block
- replacementPolicy->touch(blk);
+ replacementPolicy->touch(blk->replacementData);
} else {
// If a cache miss
lat = lookupLatency;
*/
CacheBlk* findVictim(Addr addr) override
{
+ // Get possible locations for the victim block
+ std::vector<CacheBlk*> locations = getPossibleLocations(addr);
+
// Choose replacement victim from replacement candidates
- return replacementPolicy->getVictim(getPossibleLocations(addr));
+ CacheBlk* victim = static_cast<CacheBlk*>(replacementPolicy->getVictim(
+ std::vector<ReplaceableEntry*>(
+ locations.begin(), locations.end())));
+
+ DPRINTF(CacheRepl, "set %x, way %x: selecting blk for replacement\n",
+ victim->set, victim->way);
+
+ return victim;
}
/**
}
/**
- * Insert the new block into the cache.
+ * Insert the new block into the cache and update replacement data.
+ *
* @param pkt Packet holding the address to update
* @param blk The block to update.
*/
- void insertBlock(PacketPtr pkt, CacheBlk *blk) override
- {
- Addr addr = pkt->getAddr();
- MasterID master_id = pkt->req->masterId();
- uint32_t task_id = pkt->req->taskId();
-
- if (!blk->isTouched) {
- if (!warmedUp && tagsInUse.value() >= warmupBound) {
- warmedUp = true;
- warmupCycle = curTick();
- }
- }
-
- // If we're replacing a block that was previously valid update
- // stats for it. This can't be done in findBlock() because a
- // found block might not actually be replaced there if the
- // coherence protocol says it can't be.
- if (blk->isValid()) {
- replacements[0]++;
- totalRefs += blk->refCount;
- ++sampledRefs;
-
- invalidate(blk);
- blk->invalidate();
- }
-
- // Previous block, if existed, has been removed, and now we have
- // to insert the new one
- tagsInUse++;
-
- // Set tag for new block. Caller is responsible for setting status.
- blk->tag = extractTag(addr);
-
- // deal with what we are bringing in
- assert(master_id < cache->system->maxMasters());
- occupancies[master_id]++;
- blk->srcMasterId = master_id;
- blk->task_id = task_id;
-
- // We only need to write into one tag and one data block.
- tagAccesses += 1;
- dataAccesses += 1;
-
- replacementPolicy->reset(blk);
- }
+ void insertBlock(PacketPtr pkt, CacheBlk *blk) override
+ {
+ // Insert block
+ BaseTags::insertBlock(pkt, blk);
+
+ // Update replacement policy
+ replacementPolicy->reset(blk->replacementData);
+ }
/**
* Limit the allocation for the cache ways.
* \param visitor Visitor to call on each block.
*/
void forEachBlk(CacheBlkVisitor &visitor) override {
- for (unsigned i = 0; i < numSets * assoc; ++i) {
- if (!visitor(blks[i]))
+ for (CacheBlk& blk : blks) {
+ if (!visitor(blk))
return;
}
}