fa_lru.cc revision 9086
12810Srdreslin@umich.edu/*
22810Srdreslin@umich.edu * Copyright (c) 2003-2005 The Regents of The University of Michigan
32810Srdreslin@umich.edu * All rights reserved.
42810Srdreslin@umich.edu *
52810Srdreslin@umich.edu * Redistribution and use in source and binary forms, with or without
62810Srdreslin@umich.edu * modification, are permitted provided that the following conditions are
72810Srdreslin@umich.edu * met: redistributions of source code must retain the above copyright
82810Srdreslin@umich.edu * notice, this list of conditions and the following disclaimer;
92810Srdreslin@umich.edu * redistributions in binary form must reproduce the above copyright
102810Srdreslin@umich.edu * notice, this list of conditions and the following disclaimer in the
112810Srdreslin@umich.edu * documentation and/or other materials provided with the distribution;
122810Srdreslin@umich.edu * neither the name of the copyright holders nor the names of its
132810Srdreslin@umich.edu * contributors may be used to endorse or promote products derived from
142810Srdreslin@umich.edu * this software without specific prior written permission.
152810Srdreslin@umich.edu *
162810Srdreslin@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172810Srdreslin@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182810Srdreslin@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192810Srdreslin@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202810Srdreslin@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212810Srdreslin@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222810Srdreslin@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232810Srdreslin@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242810Srdreslin@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252810Srdreslin@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262810Srdreslin@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272810Srdreslin@umich.edu *
282810Srdreslin@umich.edu * Authors: Erik Hallnor
292810Srdreslin@umich.edu */
302810Srdreslin@umich.edu
312810Srdreslin@umich.edu/**
322810Srdreslin@umich.edu * @file
332810Srdreslin@umich.edu * Definitions a fully associative LRU tagstore.
342810Srdreslin@umich.edu */
352810Srdreslin@umich.edu
366216Snate@binkert.org#include <cassert>
372810Srdreslin@umich.edu#include <sstream>
382810Srdreslin@umich.edu
392810Srdreslin@umich.edu#include "base/intmath.hh"
402814Srdreslin@umich.edu#include "base/misc.hh"
416216Snate@binkert.org#include "mem/cache/tags/fa_lru.hh"
422810Srdreslin@umich.edu
432810Srdreslin@umich.eduusing namespace std;
442810Srdreslin@umich.edu
456227Snate@binkert.orgFALRU::FALRU(unsigned _blkSize, unsigned _size, unsigned hit_latency)
466978SLisa.Hsu@amd.com    : blkSize(_blkSize), size(_size), hitLatency(hit_latency)
472810Srdreslin@umich.edu{
482810Srdreslin@umich.edu    if (!isPowerOf2(blkSize))
492810Srdreslin@umich.edu        fatal("cache block size (in bytes) `%d' must be a power of two",
502810Srdreslin@umich.edu              blkSize);
512810Srdreslin@umich.edu    if (!(hitLatency > 0))
522810Srdreslin@umich.edu        fatal("Access latency in cycles must be at least one cycle");
532810Srdreslin@umich.edu    if (!isPowerOf2(size))
542810Srdreslin@umich.edu        fatal("Cache Size must be power of 2 for now");
552810Srdreslin@umich.edu
562810Srdreslin@umich.edu    // Track all cache sizes from 128K up by powers of 2
572810Srdreslin@umich.edu    numCaches = floorLog2(size) - 17;
582810Srdreslin@umich.edu    if (numCaches >0){
592810Srdreslin@umich.edu        cacheBoundaries = new FALRUBlk *[numCaches];
602810Srdreslin@umich.edu        cacheMask = (1 << numCaches) - 1;
612810Srdreslin@umich.edu    } else {
622810Srdreslin@umich.edu        cacheMask = 0;
632810Srdreslin@umich.edu    }
642810Srdreslin@umich.edu
652810Srdreslin@umich.edu    warmedUp = false;
662810Srdreslin@umich.edu    warmupBound = size/blkSize;
676978SLisa.Hsu@amd.com    numBlocks = size/blkSize;
682810Srdreslin@umich.edu
696978SLisa.Hsu@amd.com    blks = new FALRUBlk[numBlocks];
702810Srdreslin@umich.edu    head = &(blks[0]);
716978SLisa.Hsu@amd.com    tail = &(blks[numBlocks-1]);
722810Srdreslin@umich.edu
732810Srdreslin@umich.edu    head->prev = NULL;
742810Srdreslin@umich.edu    head->next = &(blks[1]);
752810Srdreslin@umich.edu    head->inCache = cacheMask;
762810Srdreslin@umich.edu
776978SLisa.Hsu@amd.com    tail->prev = &(blks[numBlocks-2]);
782810Srdreslin@umich.edu    tail->next = NULL;
792810Srdreslin@umich.edu    tail->inCache = 0;
802810Srdreslin@umich.edu
816227Snate@binkert.org    unsigned index = (1 << 17) / blkSize;
826227Snate@binkert.org    unsigned j = 0;
832810Srdreslin@umich.edu    int flags = cacheMask;
846978SLisa.Hsu@amd.com    for (unsigned i = 1; i < numBlocks - 1; i++) {
852810Srdreslin@umich.edu        blks[i].inCache = flags;
862810Srdreslin@umich.edu        if (i == index - 1){
872810Srdreslin@umich.edu            cacheBoundaries[j] = &(blks[i]);
882810Srdreslin@umich.edu            flags &= ~ (1<<j);
892810Srdreslin@umich.edu            ++j;
902810Srdreslin@umich.edu            index = index << 1;
912810Srdreslin@umich.edu        }
922810Srdreslin@umich.edu        blks[i].prev = &(blks[i-1]);
932810Srdreslin@umich.edu        blks[i].next = &(blks[i+1]);
942810Srdreslin@umich.edu        blks[i].isTouched = false;
952810Srdreslin@umich.edu    }
962810Srdreslin@umich.edu    assert(j == numCaches);
976978SLisa.Hsu@amd.com    assert(index == numBlocks);
982810Srdreslin@umich.edu    //assert(check());
992810Srdreslin@umich.edu}
1002810Srdreslin@umich.edu
1019086Sandreas.hansson@arm.comFALRU::~FALRU()
1029086Sandreas.hansson@arm.com{
1039086Sandreas.hansson@arm.com    if (numCaches)
1049086Sandreas.hansson@arm.com        delete[] cacheBoundaries;
1059086Sandreas.hansson@arm.com
1069086Sandreas.hansson@arm.com    delete[] blks;
1079086Sandreas.hansson@arm.com}
1089086Sandreas.hansson@arm.com
1092810Srdreslin@umich.eduvoid
1102810Srdreslin@umich.eduFALRU::regStats(const string &name)
1112810Srdreslin@umich.edu{
1122810Srdreslin@umich.edu    using namespace Stats;
1132810Srdreslin@umich.edu    BaseTags::regStats(name);
1142810Srdreslin@umich.edu    hits
1152810Srdreslin@umich.edu        .init(numCaches+1)
1162810Srdreslin@umich.edu        .name(name + ".falru_hits")
1172810Srdreslin@umich.edu        .desc("The number of hits in each cache size.")
1182810Srdreslin@umich.edu        ;
1192810Srdreslin@umich.edu    misses
1202810Srdreslin@umich.edu        .init(numCaches+1)
1212810Srdreslin@umich.edu        .name(name + ".falru_misses")
1222810Srdreslin@umich.edu        .desc("The number of misses in each cache size.")
1232810Srdreslin@umich.edu        ;
1242810Srdreslin@umich.edu    accesses
1252810Srdreslin@umich.edu        .name(name + ".falru_accesses")
1262810Srdreslin@umich.edu        .desc("The number of accesses to the FA LRU cache.")
1272810Srdreslin@umich.edu        ;
1282810Srdreslin@umich.edu
1296227Snate@binkert.org    for (unsigned i = 0; i <= numCaches; ++i) {
1302810Srdreslin@umich.edu        stringstream size_str;
1312810Srdreslin@umich.edu        if (i < 3){
1322810Srdreslin@umich.edu            size_str << (1<<(i+7)) <<"K";
1332810Srdreslin@umich.edu        } else {
1342810Srdreslin@umich.edu            size_str << (1<<(i-3)) <<"M";
1352810Srdreslin@umich.edu        }
1362810Srdreslin@umich.edu
1372810Srdreslin@umich.edu        hits.subname(i, size_str.str());
1382810Srdreslin@umich.edu        hits.subdesc(i, "Hits in a " + size_str.str() +" cache");
1392810Srdreslin@umich.edu        misses.subname(i, size_str.str());
1402810Srdreslin@umich.edu        misses.subdesc(i, "Misses in a " + size_str.str() +" cache");
1412810Srdreslin@umich.edu    }
1422810Srdreslin@umich.edu}
1432810Srdreslin@umich.edu
1442810Srdreslin@umich.eduFALRUBlk *
1452810Srdreslin@umich.eduFALRU::hashLookup(Addr addr) const
1462810Srdreslin@umich.edu{
1472810Srdreslin@umich.edu    tagIterator iter = tagHash.find(addr);
1482810Srdreslin@umich.edu    if (iter != tagHash.end()) {
1492810Srdreslin@umich.edu        return (*iter).second;
1502810Srdreslin@umich.edu    }
1512810Srdreslin@umich.edu    return NULL;
1522810Srdreslin@umich.edu}
1532810Srdreslin@umich.edu
1542810Srdreslin@umich.eduvoid
1553862Sstever@eecs.umich.eduFALRU::invalidateBlk(FALRU::BlkType *blk)
1562810Srdreslin@umich.edu{
1572810Srdreslin@umich.edu    if (blk) {
1582810Srdreslin@umich.edu        blk->status = 0;
1592810Srdreslin@umich.edu        blk->isTouched = false;
1602810Srdreslin@umich.edu        tagsInUse--;
1612810Srdreslin@umich.edu    }
1622810Srdreslin@umich.edu}
1632810Srdreslin@umich.edu
1642810Srdreslin@umich.eduFALRUBlk*
1656817SLisa.Hsu@amd.comFALRU::accessBlock(Addr addr, int &lat, int context_src, int *inCache)
1662810Srdreslin@umich.edu{
1672810Srdreslin@umich.edu    accesses++;
1682810Srdreslin@umich.edu    int tmp_in_cache = 0;
1692810Srdreslin@umich.edu    Addr blkAddr = blkAlign(addr);
1702810Srdreslin@umich.edu    FALRUBlk* blk = hashLookup(blkAddr);
1712810Srdreslin@umich.edu
1722810Srdreslin@umich.edu    if (blk && blk->isValid()) {
1732810Srdreslin@umich.edu        assert(blk->tag == blkAddr);
1742810Srdreslin@umich.edu        tmp_in_cache = blk->inCache;
1756227Snate@binkert.org        for (unsigned i = 0; i < numCaches; i++) {
1762810Srdreslin@umich.edu            if (1<<i & blk->inCache) {
1772810Srdreslin@umich.edu                hits[i]++;
1782810Srdreslin@umich.edu            } else {
1792810Srdreslin@umich.edu                misses[i]++;
1802810Srdreslin@umich.edu            }
1812810Srdreslin@umich.edu        }
1822810Srdreslin@umich.edu        hits[numCaches]++;
1832810Srdreslin@umich.edu        if (blk != head){
1842810Srdreslin@umich.edu            moveToHead(blk);
1852810Srdreslin@umich.edu        }
1862810Srdreslin@umich.edu    } else {
1872810Srdreslin@umich.edu        blk = NULL;
1886227Snate@binkert.org        for (unsigned i = 0; i <= numCaches; ++i) {
1892810Srdreslin@umich.edu            misses[i]++;
1902810Srdreslin@umich.edu        }
1912810Srdreslin@umich.edu    }
1922810Srdreslin@umich.edu    if (inCache) {
1932810Srdreslin@umich.edu        *inCache = tmp_in_cache;
1942810Srdreslin@umich.edu    }
1952810Srdreslin@umich.edu
1962810Srdreslin@umich.edu    lat = hitLatency;
1972810Srdreslin@umich.edu    //assert(check());
1982810Srdreslin@umich.edu    return blk;
1992810Srdreslin@umich.edu}
2002810Srdreslin@umich.edu
2012810Srdreslin@umich.edu
2022810Srdreslin@umich.eduFALRUBlk*
2032991Srdreslin@umich.eduFALRU::findBlock(Addr addr) const
2042810Srdreslin@umich.edu{
2052810Srdreslin@umich.edu    Addr blkAddr = blkAlign(addr);
2062810Srdreslin@umich.edu    FALRUBlk* blk = hashLookup(blkAddr);
2072810Srdreslin@umich.edu
2082810Srdreslin@umich.edu    if (blk && blk->isValid()) {
2092810Srdreslin@umich.edu        assert(blk->tag == blkAddr);
2102810Srdreslin@umich.edu    } else {
2112810Srdreslin@umich.edu        blk = NULL;
2122810Srdreslin@umich.edu    }
2132810Srdreslin@umich.edu    return blk;
2142810Srdreslin@umich.edu}
2152810Srdreslin@umich.edu
2162810Srdreslin@umich.eduFALRUBlk*
2175717Shsul@eecs.umich.eduFALRU::findVictim(Addr addr, PacketList &writebacks)
2182810Srdreslin@umich.edu{
2192810Srdreslin@umich.edu    FALRUBlk * blk = tail;
2202810Srdreslin@umich.edu    assert(blk->inCache == 0);
2212810Srdreslin@umich.edu    moveToHead(blk);
2222810Srdreslin@umich.edu    tagHash.erase(blk->tag);
2234626Sstever@eecs.umich.edu    tagHash[blkAlign(addr)] = blk;
2242810Srdreslin@umich.edu    if (blk->isValid()) {
2252814Srdreslin@umich.edu        replacements[0]++;
2262810Srdreslin@umich.edu    } else {
2272810Srdreslin@umich.edu        tagsInUse++;
2282810Srdreslin@umich.edu        blk->isTouched = true;
2292810Srdreslin@umich.edu        if (!warmedUp && tagsInUse.value() >= warmupBound) {
2302810Srdreslin@umich.edu            warmedUp = true;
2317823Ssteve.reinhardt@amd.com            warmupCycle = curTick();
2322810Srdreslin@umich.edu        }
2332810Srdreslin@umich.edu    }
2342810Srdreslin@umich.edu    //assert(check());
2352810Srdreslin@umich.edu    return blk;
2362810Srdreslin@umich.edu}
2372810Srdreslin@umich.edu
2382810Srdreslin@umich.eduvoid
2396817SLisa.Hsu@amd.comFALRU::insertBlock(Addr addr, FALRU::BlkType *blk, int context_src)
2405717Shsul@eecs.umich.edu{
2415717Shsul@eecs.umich.edu}
2425717Shsul@eecs.umich.edu
2435717Shsul@eecs.umich.eduvoid
2442810Srdreslin@umich.eduFALRU::moveToHead(FALRUBlk *blk)
2452810Srdreslin@umich.edu{
2462810Srdreslin@umich.edu    int updateMask = blk->inCache ^ cacheMask;
2476227Snate@binkert.org    for (unsigned i = 0; i < numCaches; i++){
2482810Srdreslin@umich.edu        if ((1<<i) & updateMask) {
2492810Srdreslin@umich.edu            cacheBoundaries[i]->inCache &= ~(1<<i);
2502810Srdreslin@umich.edu            cacheBoundaries[i] = cacheBoundaries[i]->prev;
2512810Srdreslin@umich.edu        } else if (cacheBoundaries[i] == blk) {
2522810Srdreslin@umich.edu            cacheBoundaries[i] = blk->prev;
2532810Srdreslin@umich.edu        }
2542810Srdreslin@umich.edu    }
2552810Srdreslin@umich.edu    blk->inCache = cacheMask;
2562810Srdreslin@umich.edu    if (blk != head) {
2572810Srdreslin@umich.edu        if (blk == tail){
2582810Srdreslin@umich.edu            assert(blk->next == NULL);
2592810Srdreslin@umich.edu            tail = blk->prev;
2602810Srdreslin@umich.edu            tail->next = NULL;
2612810Srdreslin@umich.edu        } else {
2622810Srdreslin@umich.edu            blk->prev->next = blk->next;
2632810Srdreslin@umich.edu            blk->next->prev = blk->prev;
2642810Srdreslin@umich.edu        }
2652810Srdreslin@umich.edu        blk->next = head;
2662810Srdreslin@umich.edu        blk->prev = NULL;
2672810Srdreslin@umich.edu        head->prev = blk;
2682810Srdreslin@umich.edu        head = blk;
2692810Srdreslin@umich.edu    }
2702810Srdreslin@umich.edu}
2712810Srdreslin@umich.edu
2722810Srdreslin@umich.edubool
2732810Srdreslin@umich.eduFALRU::check()
2742810Srdreslin@umich.edu{
2752810Srdreslin@umich.edu    FALRUBlk* blk = head;
2762810Srdreslin@umich.edu    int size = 0;
2772810Srdreslin@umich.edu    int boundary = 1<<17;
2782810Srdreslin@umich.edu    int j = 0;
2792810Srdreslin@umich.edu    int flags = cacheMask;
2802810Srdreslin@umich.edu    while (blk) {
2812810Srdreslin@umich.edu        size += blkSize;
2822810Srdreslin@umich.edu        if (blk->inCache != flags) {
2832810Srdreslin@umich.edu            return false;
2842810Srdreslin@umich.edu        }
2852810Srdreslin@umich.edu        if (size == boundary && blk != tail) {
2862810Srdreslin@umich.edu            if (cacheBoundaries[j] != blk) {
2872810Srdreslin@umich.edu                return false;
2882810Srdreslin@umich.edu            }
2892810Srdreslin@umich.edu            flags &=~(1 << j);
2902810Srdreslin@umich.edu            boundary = boundary<<1;
2912810Srdreslin@umich.edu            ++j;
2922810Srdreslin@umich.edu        }
2932810Srdreslin@umich.edu        blk = blk->next;
2942810Srdreslin@umich.edu    }
2952810Srdreslin@umich.edu    return true;
2962810Srdreslin@umich.edu}
2977612SGene.Wu@arm.com
2987612SGene.Wu@arm.comvoid
2997612SGene.Wu@arm.comFALRU::clearLocks()
3007612SGene.Wu@arm.com{
3017612SGene.Wu@arm.com    for (int i = 0; i < numBlocks; i++){
3027612SGene.Wu@arm.com        blks[i].clearLoadLocks();
3037612SGene.Wu@arm.com    }
3047612SGene.Wu@arm.com}
305