fa_lru.cc

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

CC
293
字号
/* * Copyright (c) 2003, 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: Erik G. Hallnor *//** * @file * Definitions a fully associative LRU tagstore. */#include <sstream>#include <assert.h>#include "mem/cache/tags/fa_lru.hh"#include "base/intmath.hh"#include "base/misc.hh"using namespace std;FALRU::FALRU(int _blkSize, int _size, int hit_latency)    : blkSize(_blkSize), size(_size),      numBlks(size/blkSize), hitLatency(hit_latency){    if (!isPowerOf2(blkSize))        fatal("cache block size (in bytes) `%d' must be a power of two",              blkSize);    if (!(hitLatency > 0))        fatal("Access latency in cycles must be at least one cycle");    if (!isPowerOf2(size))        fatal("Cache Size must be power of 2 for now");    // Track all cache sizes from 128K up by powers of 2    numCaches = floorLog2(size) - 17;    if (numCaches >0){        cacheBoundaries = new FALRUBlk *[numCaches];        cacheMask = (1 << numCaches) - 1;    } else {        cacheMask = 0;    }    warmedUp = false;    warmupBound = size/blkSize;    blks = new FALRUBlk[numBlks];    head = &(blks[0]);    tail = &(blks[numBlks-1]);    head->prev = NULL;    head->next = &(blks[1]);    head->inCache = cacheMask;    tail->prev = &(blks[numBlks-2]);    tail->next = NULL;    tail->inCache = 0;    int index = (1 << 17) / blkSize;    int j = 0;    int flags = cacheMask;    for (int i = 1; i < numBlks-1; i++) {        blks[i].inCache = flags;        if (i == index - 1){            cacheBoundaries[j] = &(blks[i]);            flags &= ~ (1<<j);            ++j;            index = index << 1;        }        blks[i].prev = &(blks[i-1]);        blks[i].next = &(blks[i+1]);        blks[i].isTouched = false;    }    assert(j == numCaches);    assert(index == numBlks);    //assert(check());}voidFALRU::regStats(const string &name){    using namespace Stats;    BaseTags::regStats(name);    hits        .init(numCaches+1)        .name(name + ".falru_hits")        .desc("The number of hits in each cache size.")        ;    misses        .init(numCaches+1)        .name(name + ".falru_misses")        .desc("The number of misses in each cache size.")        ;    accesses        .name(name + ".falru_accesses")        .desc("The number of accesses to the FA LRU cache.")        ;    for (int i = 0; i < numCaches+1; ++i) {        stringstream size_str;        if (i < 3){            size_str << (1<<(i+7)) <<"K";        } else {            size_str << (1<<(i-3)) <<"M";        }        hits.subname(i, size_str.str());        hits.subdesc(i, "Hits in a " + size_str.str() +" cache");        misses.subname(i, size_str.str());        misses.subdesc(i, "Misses in a " + size_str.str() +" cache");    }}FALRUBlk *FALRU::hashLookup(Addr addr) const{    tagIterator iter = tagHash.find(addr);    if (iter != tagHash.end()) {        return (*iter).second;    }    return NULL;}boolFALRU::probe(Addr addr) const{    Addr blkAddr = blkAlign(addr);    FALRUBlk* blk = hashLookup(blkAddr);    return blk && blk->tag == blkAddr && blk->isValid();}voidFALRU::invalidateBlk(FALRU::BlkType *blk){    if (blk) {        blk->status = 0;        blk->isTouched = false;        tagsInUse--;    }}FALRUBlk*FALRU::findBlock(Addr addr, int &lat, int *inCache){    accesses++;    int tmp_in_cache = 0;    Addr blkAddr = blkAlign(addr);    FALRUBlk* blk = hashLookup(blkAddr);    if (blk && blk->isValid()) {        assert(blk->tag == blkAddr);        tmp_in_cache = blk->inCache;        for (int i = 0; i < numCaches; i++) {            if (1<<i & blk->inCache) {                hits[i]++;            } else {                misses[i]++;            }        }        hits[numCaches]++;        if (blk != head){            moveToHead(blk);        }    } else {        blk = NULL;        for (int i = 0; i < numCaches+1; ++i) {            misses[i]++;        }    }    if (inCache) {        *inCache = tmp_in_cache;    }    lat = hitLatency;    //assert(check());    return blk;}FALRUBlk*FALRU::findBlock(Addr addr) const{    Addr blkAddr = blkAlign(addr);    FALRUBlk* blk = hashLookup(blkAddr);    if (blk && blk->isValid()) {        assert(blk->tag == blkAddr);    } else {        blk = NULL;    }    return blk;}FALRUBlk*FALRU::findReplacement(Addr addr, PacketList &writebacks){    FALRUBlk * blk = tail;    assert(blk->inCache == 0);    moveToHead(blk);    tagHash.erase(blk->tag);    tagHash[blkAlign(addr)] = blk;    if (blk->isValid()) {        replacements[0]++;    } else {        tagsInUse++;        blk->isTouched = true;        if (!warmedUp && tagsInUse.value() >= warmupBound) {            warmedUp = true;            warmupCycle = curTick;        }    }    //assert(check());    return blk;}voidFALRU::moveToHead(FALRUBlk *blk){    int updateMask = blk->inCache ^ cacheMask;    for (int i = 0; i < numCaches; i++){        if ((1<<i) & updateMask) {            cacheBoundaries[i]->inCache &= ~(1<<i);            cacheBoundaries[i] = cacheBoundaries[i]->prev;        } else if (cacheBoundaries[i] == blk) {            cacheBoundaries[i] = blk->prev;        }    }    blk->inCache = cacheMask;    if (blk != head) {        if (blk == tail){            assert(blk->next == NULL);            tail = blk->prev;            tail->next = NULL;        } else {            blk->prev->next = blk->next;            blk->next->prev = blk->prev;        }        blk->next = head;        blk->prev = NULL;        head->prev = blk;        head = blk;    }}boolFALRU::check(){    FALRUBlk* blk = head;    int size = 0;    int boundary = 1<<17;    int j = 0;    int flags = cacheMask;    while (blk) {        size += blkSize;        if (blk->inCache != flags) {            return false;        }        if (size == boundary && blk != tail) {            if (cacheBoundaries[j] != blk) {                return false;            }            flags &=~(1 << j);            boundary = boundary<<1;            ++j;        }        blk = blk->next;    }    return true;}

⌨️ 快捷键说明

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