/** * Find an invalid block to evict for the address provided. * If there are no invalid blocks, this will return the block * in the least-recently-used position. * @param addr The addr to a find a replacement candidate for. * @return The candidate block. */ CacheBlk* findVictim(Addr addr) override { BlkType *blk = nullptr; intset = extractSet(addr);
// prefer to evict an invalid block for (int i = 0; i < allocAssoc; ++i) { blk = sets[set].blks[i]; if (!blk->isValid()) break; }
// 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. //如果blk旧块为isValid,好像意思就是该块不为空,一系列操作后标记blk //为invalidate,lru.cc中还将其移到淘汰优先级队列末位,下一步马上被淘汰,并且为isTouched。 if (blk->isValid()) { lru.cc中还将其移到淘汰优先级队列末位,下一步马上被淘汰,并且为isTouched。 if (blk->isValid()) { replacements[0]++; totalRefs += blk->refCount; ++sampledRefs; blk->refCount = 0;
// deal with evicted block assert(blk->srcMasterId < cache->system->maxMasters()); occupancies[blk->srcMasterId]--;
blk->invalidate(); }
blk->isTouched = true;
// 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; blk->tickInserted = curTick();
// We only need to write into one tag and one data block. tagAccesses += 1; dataAccesses += 1; }