split_lru.cc

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· CC 代码 · 共 261 行

CC
261
字号
/* * Copyright (c) 2004, 2005 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. * * Authors: Lisa R. Hsu *//** * @file * Definitions of LRU tag store for a partitioned cache. */#include <string>#include "mem/cache/base.hh"#include "base/intmath.hh"#include "mem/cache/tags/split_lru.hh"#include "sim/core.hh"using namespace std;SplitBlk*SplitCacheSet::findBlk(Addr tag) const{    for (int i = 0; i < assoc; ++i) {        if (blks[i]->tag == tag && blks[i]->isValid()) {            return blks[i];        }    }    return 0;}voidSplitCacheSet::moveToHead(SplitBlk *blk){    // nothing to do if blk is already head    if (blks[0] == blk)        return;    // write 'next' block into blks[i], moving up from MRU toward LRU    // until we overwrite the block we moved to head.    // start by setting up to write 'blk' into blks[0]    int i = 0;    SplitBlk *next = blk;    do {        assert(i < assoc);        // swap blks[i] and next        SplitBlk *tmp = blks[i];        blks[i] = next;        next = tmp;        ++i;    } while (next != blk);}// create and initialize a LRU/MRU cache structureSplitLRU::SplitLRU(int _numSets, int _blkSize, int _assoc, int _hit_latency, int _part) :    numSets(_numSets), blkSize(_blkSize), assoc(_assoc), hitLatency(_hit_latency), part(_part){    // Check parameters    if (blkSize < 4 || !isPowerOf2(blkSize)) {        fatal("Block size must be at least 4 and a power of 2");    }    if (numSets <= 0 || !isPowerOf2(numSets)) {        fatal("# of sets must be non-zero and a power of 2");    }    if (assoc <= 0) {        fatal("associativity must be greater than zero");    }    if (hitLatency <= 0) {        fatal("access latency must be greater than zero");    }    SplitBlk  *blk;    int i, j, blkIndex;    blkMask = blkSize - 1;    setShift = floorLog2(blkSize);    setMask = numSets - 1;    tagShift = setShift + floorLog2(numSets);    warmedUp = false;    /** @todo Make warmup percentage a parameter. */    warmupBound = numSets * assoc;    sets = new SplitCacheSet[numSets];    blks = new SplitBlk[numSets * assoc];    // allocate data storage in one big chunk    dataBlks = new uint8_t[numSets*assoc*blkSize];    blkIndex = 0;	// index into blks array    for (i = 0; i < numSets; ++i) {        sets[i].assoc = assoc;        sets[i].blks = new SplitBlk*[assoc];        // link in the data blocks        for (j = 0; j < assoc; ++j) {            // locate next cache block            blk = &blks[blkIndex];            blk->data = &dataBlks[blkSize*blkIndex];            ++blkIndex;            // invalidate new cache block            blk->status = 0;            //EGH Fix Me : do we need to initialize blk?            // Setting the tag to j is just to prevent long chains in the hash            // table; won't matter because the block is invalid            blk->tag = j;            blk->whenReady = 0;            blk->isTouched = false;            blk->size = blkSize;            sets[i].blks[j]=blk;            blk->set = i;            blk->part = part;        }    }}SplitLRU::~SplitLRU(){    delete [] dataBlks;    delete [] blks;    delete [] sets;}voidSplitLRU::regStats(const std::string &name){    BaseTags::regStats(name);    hits        .name(name + ".hits")        .desc("number of hits on this partition")        .precision(0)        ;    misses        .name(name + ".misses")        .desc("number of misses in this partition")        .precision(0)        ;}// probe cache for presence of given block.boolSplitLRU::probe(Addr addr) const{    //  return(findBlock(Read, addr, asid) != 0);    Addr tag = extractTag(addr);    unsigned myset = extractSet(addr);    SplitBlk *blk = sets[myset].findBlk(tag);    return (blk != NULL);	// true if in cache}SplitBlk*SplitLRU::findBlock(Addr addr, int &lat){    Addr tag = extractTag(addr);    unsigned set = extractSet(addr);    SplitBlk *blk = sets[set].findBlk(tag);    lat = hitLatency;    if (blk != NULL) {        // move this block to head of the MRU list        sets[set].moveToHead(blk);        if (blk->whenReady > curTick && blk->whenReady - curTick > hitLatency){            lat = blk->whenReady - curTick;        }        blk->refCount += 1;        hits++;    }    return blk;}SplitBlk*SplitLRU::findBlock(Addr addr) const{    Addr tag = extractTag(addr);    unsigned set = extractSet(addr);    SplitBlk *blk = sets[set].findBlk(tag);    return blk;}SplitBlk*SplitLRU::findReplacement(Addr addr, PacketList &writebacks){    unsigned set = extractSet(addr);    // grab a replacement candidate    SplitBlk *blk = sets[set].blks[assoc-1];    sets[set].moveToHead(blk);    if (blk->isValid()) {        replacements[0]++;        totalRefs += blk->refCount;        ++sampledRefs;        blk->refCount = 0;    } else if (!blk->isTouched) {        tagsInUse++;        blk->isTouched = true;        if (!warmedUp && tagsInUse.value() >= warmupBound) {            warmedUp = true;            warmupCycle = curTick;        }    }    misses++;    return blk;}voidSplitLRU::invalidateBlk(SplitLRU::BlkType *blk){    if (blk) {        blk->status = 0;        blk->isTouched = false;        tagsInUse--;    }}voidSplitLRU::cleanupRefs(){    for (int i = 0; i < numSets*assoc; ++i) {        if (blks[i].isValid()) {            totalRefs += blks[i].refCount;            ++sampledRefs;        }    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?