diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mem/cache/BaseCache.py | 5 | ||||
-rw-r--r-- | src/mem/cache/builder.cc | 36 | ||||
-rw-r--r-- | src/mem/cache/cache.cc | 16 | ||||
-rw-r--r-- | src/mem/cache/tags/SConscript | 4 | ||||
-rw-r--r-- | src/mem/cache/tags/split.cc | 419 | ||||
-rw-r--r-- | src/mem/cache/tags/split.hh | 308 | ||||
-rw-r--r-- | src/mem/cache/tags/split_blk.hh | 68 | ||||
-rw-r--r-- | src/mem/cache/tags/split_lifo.cc | 331 | ||||
-rw-r--r-- | src/mem/cache/tags/split_lifo.hh | 312 | ||||
-rw-r--r-- | src/mem/cache/tags/split_lru.cc | 260 | ||||
-rw-r--r-- | src/mem/cache/tags/split_lru.hh | 295 | ||||
-rw-r--r-- | src/mem/config/cache.hh | 3 |
12 files changed, 1 insertions, 2056 deletions
diff --git a/src/mem/cache/BaseCache.py b/src/mem/cache/BaseCache.py index f6d42b1ef..936107b7f 100644 --- a/src/mem/cache/BaseCache.py +++ b/src/mem/cache/BaseCache.py @@ -38,8 +38,6 @@ class BaseCache(MemObject): block_size = Param.Int("block size in bytes") latency = Param.Latency("Latency") hash_delay = Param.Int(1, "time in cycles of hash access") - lifo = Param.Bool(False, - "whether this NIC partition should use LIFO repl. policy") max_miss_count = Param.Counter(0, "number of misses to handle before calling exit") mshrs = Param.Int("number of MSHRs (max outstanding requests)") @@ -47,9 +45,6 @@ class BaseCache(MemObject): "always service demand misses first") repl = Param.Repl(NULL, "replacement policy") size = Param.MemorySize("capacity in bytes") - split = Param.Bool(False, "whether or not this cache is split") - split_size = Param.Int(0, - "How many ways of the cache belong to CPU/LRU partition") subblock_size = Param.Int(0, "Size of subblock in IIC used for compression") tgts_per_mshr = Param.Int("max number of accesses per MSHR") diff --git a/src/mem/cache/builder.cc b/src/mem/cache/builder.cc index 97930fe60..27daa4025 100644 --- a/src/mem/cache/builder.cc +++ b/src/mem/cache/builder.cc @@ -57,14 +57,6 @@ #include "mem/cache/tags/iic.hh" #endif -#if defined(USE_CACHE_SPLIT) -#include "mem/cache/tags/split.hh" -#endif - -#if defined(USE_CACHE_SPLIT_LIFO) -#include "mem/cache/tags/split_lifo.hh" -#endif - //Prefetcher Headers #if defined(USE_GHB) #include "mem/cache/prefetch/ghb.hh" @@ -122,26 +114,6 @@ using namespace TheISA; #define BUILD_LRU_CACHE BUILD_CACHE_PANIC("lru cache") #endif -#if defined(USE_CACHE_SPLIT) -#define BUILD_SPLIT_CACHE do { \ - Split *tags = new Split(numSets, block_size, assoc, split_size, lifo, \ - two_queue, latency); \ - BUILD_CACHE(Split, tags); \ - } while (0) -#else -#define BUILD_SPLIT_CACHE BUILD_CACHE_PANIC("split cache") -#endif - -#if defined(USE_CACHE_SPLIT_LIFO) -#define BUILD_SPLIT_LIFO_CACHE do { \ - SplitLIFO *tags = new SplitLIFO(block_size, size, assoc, \ - latency, two_queue, -1); \ - BUILD_CACHE(SplitLIFO, tags); \ - } while (0) -#else -#define BUILD_SPLIT_LIFO_CACHE BUILD_CACHE_PANIC("lifo cache") -#endif - #if defined(USE_CACHE_IIC) #define BUILD_IIC_CACHE do { \ IIC *tags = new IIC(iic_params); \ @@ -156,13 +128,7 @@ using namespace TheISA; if (numSets == 1) { \ BUILD_FALRU_CACHE; \ } else { \ - if (split == true) { \ - BUILD_SPLIT_CACHE; \ - } else if (lifo == true) { \ - BUILD_SPLIT_LIFO_CACHE; \ - } else { \ - BUILD_LRU_CACHE; \ - } \ + BUILD_LRU_CACHE; \ } \ } else { \ BUILD_IIC_CACHE; \ diff --git a/src/mem/cache/cache.cc b/src/mem/cache/cache.cc index c640d4a60..d403535fc 100644 --- a/src/mem/cache/cache.cc +++ b/src/mem/cache/cache.cc @@ -50,14 +50,6 @@ #include "mem/cache/tags/iic.hh" #endif -#if defined(USE_CACHE_SPLIT) -#include "mem/cache/tags/split.hh" -#endif - -#if defined(USE_CACHE_SPLIT_LIFO) -#include "mem/cache/tags/split_lifo.hh" -#endif - #include "mem/cache/cache_impl.hh" // Template Instantiations @@ -76,12 +68,4 @@ template class Cache<IIC>; template class Cache<LRU>; #endif -#if defined(USE_CACHE_SPLIT) -template class Cache<Split>; -#endif - -#if defined(USE_CACHE_SPLIT_LIFO) -template class Cache<SplitLIFO>; -#endif - #endif //DOXYGEN_SHOULD_SKIP_THIS diff --git a/src/mem/cache/tags/SConscript b/src/mem/cache/tags/SConscript index 9153d97e7..7255e0b7e 100644 --- a/src/mem/cache/tags/SConscript +++ b/src/mem/cache/tags/SConscript @@ -34,13 +34,9 @@ Source('base.cc') Source('fa_lru.cc') Source('iic.cc') Source('lru.cc') -Source('split.cc') -Source('split_lifo.cc') -Source('split_lru.cc') SimObject('iic_repl/Repl.py') Source('iic_repl/gen.cc') TraceFlag('IIC') TraceFlag('IICMore') -TraceFlag('Split') diff --git a/src/mem/cache/tags/split.cc b/src/mem/cache/tags/split.cc deleted file mode 100644 index 5bed44bd3..000000000 --- a/src/mem/cache/tags/split.cc +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright (c) 2004-2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Lisa Hsu - */ - -/** - * @file - * Definitions of split cache tag store. - */ - -#include <string> -#include <iostream> -#include <fstream> - -#include "base/cprintf.hh" -#include "base/intmath.hh" -#include "base/output.hh" -#include "base/trace.hh" -#include "mem/cache/base.hh" -#include "mem/cache/tags/split.hh" -#include "mem/cache/tags/split_lifo.hh" -#include "mem/cache/tags/split_lru.hh" - - -using namespace std; -using namespace TheISA; - -// create and initialize a partitioned cache structure -Split::Split(int _numSets, int _blkSize, int total_ways, int LRU1_assoc, - bool _lifo, bool _two_queue, int _hit_latency) : - numSets(_numSets), blkSize(_blkSize), lifo(_lifo), hitLatency(_hit_latency) -{ - DPRINTF(Split, "new split cache!!\n"); - - DPRINTF(Split, "lru has %d numSets, %d blkSize, %d assoc, and %d hit_latency\n", - numSets, blkSize, LRU1_assoc, hitLatency); - - lru = new SplitLRU(_numSets, _blkSize, LRU1_assoc, _hit_latency, 1); - - if (total_ways - LRU1_assoc == 0) { - lifo_net = NULL; - lru_net = NULL; - } else { - if (lifo) { - DPRINTF(Split, "Other partition is a LIFO with size %d in bytes. it gets %d ways\n", - (total_ways - LRU1_assoc)*_numSets*_blkSize, (total_ways - LRU1_assoc)); - lifo_net = new SplitLIFO(_blkSize, (total_ways - LRU1_assoc)*_numSets*_blkSize, - (total_ways - LRU1_assoc), _hit_latency, _two_queue, 2); - lru_net = NULL; - } - else { - DPRINTF(Split, "other LRU gets %d ways\n", total_ways - LRU1_assoc); - lru_net = new SplitLRU(_numSets, _blkSize, total_ways - LRU1_assoc, _hit_latency, 2); - lifo_net = NULL; - } - } - - blkMask = blkSize - 1; - - if (!isPowerOf2(total_ways)) - warn("total cache ways/columns %d should be power of 2", - total_ways); - - warmedUp = false; - /** @todo Make warmup percentage a parameter. */ - warmupBound = numSets * total_ways; - -} - -Split::~Split() -{ - delete lru; - if (lifo) - delete lifo_net; - else - delete lru_net; -} - -void -Split::regStats(const string &name) -{ - using namespace Stats; - - BaseTags::regStats(name); - - usedEvictDist.init(0,3000,40); - unusedEvictDist.init(0,3000,40); - useByCPUCycleDist.init(0,35,1); - - nic_repl - .name(name + ".nic_repl") - .desc("number of replacements in the nic partition") - .precision(0) - ; - - cpu_repl - .name(name + ".cpu_repl") - .desc("number of replacements in the cpu partition") - .precision(0) - ; - - lru->regStats(name + ".lru"); - - if (lifo && lifo_net) { - lifo_net->regStats(name + ".lifo_net"); - } else if (lru_net) { - lru_net->regStats(name + ".lru_net"); - } - - nicUsedWhenEvicted - .name(name + ".nicUsedWhenEvicted") - .desc("number of NIC blks that were used before evicted") - ; - - nicUsedTotLatency - .name(name + ".nicUsedTotLatency") - .desc("total cycles before eviction of used NIC blks") - ; - - nicUsedTotEvicted - .name(name + ".nicUsedTotEvicted") - .desc("total number of used NIC blks evicted") - ; - - nicUsedAvgLatency - .name(name + ".nicUsedAvgLatency") - .desc("avg number of cycles a used NIC blk is in cache") - .precision(0) - ; - nicUsedAvgLatency = nicUsedTotLatency / nicUsedTotEvicted; - - usedEvictDist - .name(name + ".usedEvictDist") - .desc("distribution of used NIC blk eviction times") - .flags(pdf | cdf) - ; - - nicUnusedWhenEvicted - .name(name + ".nicUnusedWhenEvicted") - .desc("number of NIC blks that were unused when evicted") - ; - - nicUnusedTotLatency - .name(name + ".nicUnusedTotLatency") - .desc("total cycles before eviction of unused NIC blks") - ; - - nicUnusedTotEvicted - .name(name + ".nicUnusedTotEvicted") - .desc("total number of unused NIC blks evicted") - ; - - nicUnusedAvgLatency - .name(name + ".nicUnusedAvgLatency") - .desc("avg number of cycles an unused NIC blk is in cache") - .precision(0) - ; - nicUnusedAvgLatency = nicUnusedTotLatency / nicUnusedTotEvicted; - - unusedEvictDist - .name(name + ".unusedEvictDist") - .desc("distribution of unused NIC blk eviction times") - .flags(pdf | cdf) - ; - - nicUseByCPUCycleTotal - .name(name + ".nicUseByCPUCycleTotal") - .desc("total latency of NIC blks til usage time") - ; - - nicBlksUsedByCPU - .name(name + ".nicBlksUsedByCPU") - .desc("total number of NIC blks used") - ; - - nicAvgUsageByCPULatency - .name(name + ".nicAvgUsageByCPULatency") - .desc("average number of cycles before a NIC blk that is used gets used") - .precision(0) - ; - nicAvgUsageByCPULatency = nicUseByCPUCycleTotal / nicBlksUsedByCPU; - - useByCPUCycleDist - .name(name + ".useByCPUCycleDist") - .desc("the distribution of cycle time in cache before NIC blk is used") - .flags(pdf | cdf) - ; - - cpuUsedBlks - .name(name + ".cpuUsedBlks") - .desc("number of cpu blks that were used before evicted") - ; - - cpuUnusedBlks - .name(name + ".cpuUnusedBlks") - .desc("number of cpu blks that were unused before evicted") - ; - - nicAvgLatency - .name(name + ".nicAvgLatency") - .desc("avg number of cycles a NIC blk is in cache before evicted") - .precision(0) - ; - nicAvgLatency = (nicUnusedTotLatency + nicUsedTotLatency) / - (nicUnusedTotEvicted + nicUsedTotEvicted); - - NR_CP_hits - .name(name + ".NR_CP_hits") - .desc("NIC requests hitting in CPU Partition") - ; - - NR_NP_hits - .name(name + ".NR_NP_hits") - .desc("NIC requests hitting in NIC Partition") - ; - - CR_CP_hits - .name(name + ".CR_CP_hits") - .desc("CPU requests hitting in CPU partition") - ; - - CR_NP_hits - .name(name + ".CR_NP_hits") - .desc("CPU requests hitting in NIC partition") - ; - -} - -// probe cache for presence of given block. -bool -Split::probe(Addr addr) const -{ - bool success = lru->probe(addr); - if (!success) { - if (lifo && lifo_net) - success = lifo_net->probe(addr); - else if (lru_net) - success = lru_net->probe(addr); - } - - return success; -} - - -SplitBlk* -Split::findBlock(Addr addr, int &lat) -{ - SplitBlk *blk = lru->findBlock(addr, lat); - if (!blk) { - if (lifo && lifo_net) { - blk = lifo_net->findBlock(addr, lat); - } else if (lru_net) { - blk = lru_net->findBlock(addr, lat); - } - } - - return blk; -} - -SplitBlk* -Split::findBlock(Addr addr) const -{ - SplitBlk *blk = lru->findBlock(addr); - if (!blk) { - if (lifo && lifo_net) { - blk = lifo_net->findBlock(addr); - } else if (lru_net) { - blk = lru_net->findBlock(addr); - } - } - - return blk; -} - -SplitBlk* -Split::findReplacement(Addr addr, PacketList &writebacks) -{ - SplitBlk *blk = NULL; - - assert(0); -#if 0 - if (pkt->nic_pkt()) { - DPRINTF(Split, "finding a replacement for nic_req\n"); - nic_repl++; - if (lifo && lifo_net) - blk = lifo_net->findReplacement(addr, writebacks); - else if (lru_net) - blk = lru_net->findReplacement(addr, writebacks); - // in this case, this is an LRU only cache, it's non partitioned - else - blk = lru->findReplacement(addr, writebacks); - } else { - DPRINTF(Split, "finding replacement for cpu_req\n"); - blk = lru->findReplacement(addr, writebacks); - cpu_repl++; - } - - Tick latency = curTick - blk->ts; - if (blk->isNIC) { - if (blk->isUsed) { - nicUsedWhenEvicted++; - usedEvictDist.sample(latency); - nicUsedTotLatency += latency; - nicUsedTotEvicted++; - } else { - nicUnusedWhenEvicted++; - unusedEvictDist.sample(latency); - nicUnusedTotLatency += latency; - nicUnusedTotEvicted++; - } - } else { - if (blk->isUsed) { - cpuUsedBlks++; - } else { - cpuUnusedBlks++; - } - } - - // blk attributes for the new blk coming IN - blk->ts = curTick; - blk->isNIC = (pkt->nic_pkt()) ? true : false; -#endif - - return blk; -} - -void -Split::invalidateBlk(Split::BlkType *blk) -{ - if (!blk) { - fatal("FIXME!\n"); -#if 0 - if (lifo && lifo_net) - blk = lifo_net->findBlock(addr); - else if (lru_net) - blk = lru_net->findBlock(addr); -#endif - - if (!blk) - return; - } - - blk->status = 0; - blk->isTouched = false; - tagsInUse--; -} - -void -Split::cleanupRefs() -{ - lru->cleanupRefs(); - if (lifo && lifo_net) - lifo_net->cleanupRefs(); - else if (lru_net) - lru_net->cleanupRefs(); - - ostream *memPrint = simout.create("memory_footprint.txt"); - - // this shouldn't be here but it happens at the end, which is what i want - memIter end = memHash.end(); - for (memIter iter = memHash.begin(); iter != end; ++iter) { - ccprintf(*memPrint, "%8x\t%d\n", (*iter).first, (*iter).second); - } -} - -Addr -Split::regenerateBlkAddr(Addr tag, int set) const -{ - if (lifo_net) - return lifo_net->regenerateBlkAddr(tag, set); - else - return lru->regenerateBlkAddr(tag, set); -} - -Addr -Split::extractTag(Addr addr) const -{ - // need to fix this if we want to use it... old interface of - // passing in blk was too weird - assert(0); - return 0; -/* - if (blk->part == 2) { - if (lifo_net) - return lifo_net->extractTag(addr); - else if (lru_net) - return lru_net->extractTag(addr); - else - panic("this shouldn't happen"); - } else - return lru->extractTag(addr); -*/ -} - diff --git a/src/mem/cache/tags/split.hh b/src/mem/cache/tags/split.hh deleted file mode 100644 index e8954f791..000000000 --- a/src/mem/cache/tags/split.hh +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright (c) 2004-2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Lisa Hsu - */ - -/** - * @file - * Declaration of a split/partitioned tag store. - */ - -#ifndef __SPLIT_HH__ -#define __SPLIT_HH__ - -#include <cstring> -#include <list> - -#include "mem/cache/blk.hh" // base class -#include "mem/cache/tags/split_blk.hh" -#include "mem/packet.hh" // for inlined functions -#include <assert.h> -#include "mem/cache/tags/base.hh" -#include "base/hashmap.hh" - -class BaseCache; -class SplitLRU; -class SplitLIFO; - -/** - * A cache tag store. - */ -class Split : public BaseTags -{ - public: - /** Typedef the block type used in this tag store. */ - typedef SplitBlk BlkType; - /** Typedef for a list of pointers to the local block class. */ - typedef std::list<SplitBlk*> BlkList; - protected: - /** The number of sets in the cache. */ - const int numSets; - /** The number of bytes in a block. */ - const int blkSize; - /** Whether the 2nd partition (for the nic) is LIFO or not */ - const bool lifo; - /** The hit latency. */ - const int hitLatency; - - Addr blkMask; - - /** Number of NIC requests that hit in the NIC partition */ - Stats::Scalar<> NR_NP_hits; - /** Number of NIC requests that hit in the CPU partition */ - Stats::Scalar<> NR_CP_hits; - /** Number of CPU requests that hit in the NIC partition */ - Stats::Scalar<> CR_NP_hits; - /** Number of CPU requests that hit in the CPU partition */ - Stats::Scalar<> CR_CP_hits; - /** The number of nic replacements (i.e. misses) */ - Stats::Scalar<> nic_repl; - /** The number of cpu replacements (i.e. misses) */ - Stats::Scalar<> cpu_repl; - - //For latency studies - /** the number of NIC blks that were used before evicted */ - Stats::Scalar<> nicUsedWhenEvicted; - /** the total latency of used NIC blocks in the cache */ - Stats::Scalar<> nicUsedTotLatency; - /** the total number of used NIC blocks evicted */ - Stats::Scalar<> nicUsedTotEvicted; - /** the average number of cycles a used NIC blk is in the cache */ - Stats::Formula nicUsedAvgLatency; - /** the Distribution of used NIC blk eviction times */ - Stats::Distribution<> usedEvictDist; - - /** the number of NIC blks that were unused before evicted */ - Stats::Scalar<> nicUnusedWhenEvicted; - /** the total latency of unused NIC blks in the cache */ - Stats::Scalar<> nicUnusedTotLatency; - /** the total number of unused NIC blocks evicted */ - Stats::Scalar<> nicUnusedTotEvicted; - /** the average number of cycles an unused NIC blk is in the cache */ - Stats::Formula nicUnusedAvgLatency; - /** the Distribution of unused NIC blk eviction times */ - Stats::Distribution<> unusedEvictDist; - - /** The total latency of NIC blocks to 1st usage time by CPU */ - Stats::Scalar<> nicUseByCPUCycleTotal; - /** The total number of NIC blocks used */ - Stats::Scalar<> nicBlksUsedByCPU; - /** the average number of cycles before a NIC blk that is used gets used by CPU */ - Stats::Formula nicAvgUsageByCPULatency; - /** the Distribution of cycles time before a NIC blk is used by CPU*/ - Stats::Distribution<> useByCPUCycleDist; - - /** the number of CPU blks that were used before evicted */ - Stats::Scalar<> cpuUsedBlks; - /** the number of CPU blks that were unused before evicted */ - Stats::Scalar<> cpuUnusedBlks; - - /** the avg number of cycles before a NIC blk is evicted */ - Stats::Formula nicAvgLatency; - - typedef m5::hash_map<Addr, int, m5::hash<Addr> > hash_t; - typedef hash_t::const_iterator memIter; - hash_t memHash; - - - private: - SplitLRU *lru; - SplitLRU *lru_net; - SplitLIFO *lifo_net; - - public: - /** - * Construct and initialize this tag store. - * @param _numSets The number of sets in the cache. - * @param _blkSize The number of bytes in a block. - * @param _assoc The associativity of the cache. - * @param _hit_latency The latency in cycles for a hit. - */ - Split(int _numSets, int _blkSize, int total_ways, int LRU1_assoc, - bool _lifo, bool _two_queue, int _hit_latency); - - /** - * Destructor - */ - virtual ~Split(); - - /** - * Register the stats for this object - * @param name The name to prepend to the stats name. - */ - void regStats(const std::string &name); - - /** - * Return the block size. - * @return the block size. - */ - int getBlockSize() - { - return blkSize; - } - - /** - * Return the subblock size. In the case of Split it is always the block - * size. - * @return The block size. - */ - int getSubBlockSize() - { - return blkSize; - } - - /** - * Search for the address in the cache. - * @param asid The address space ID. - * @param addr The address to find. - * @return True if the address is in the cache. - */ - bool probe(Addr addr) const; - - /** - * Invalidate the given block. - * @param blk The block to invalidate. - */ - void invalidateBlk(BlkType *blk); - - /** - * Finds the given address in the cache and update replacement data. - * Returns the access latency as a side effect. - * @param addr The address to find. - * @param asid The address space ID. - * @param lat The access latency. - * @return Pointer to the cache block if found. - */ - SplitBlk* findBlock(Addr addr, int &lat); - - /** - * Finds the given address in the cache, do not update replacement data. - * @param addr The address to find. - * @param asid The address space ID. - * @return Pointer to the cache block if found. - */ - SplitBlk* findBlock(Addr addr) const; - - /** - * Find a replacement block for the address provided. - * @param pkt The request to a find a replacement candidate for. - * @param writebacks List for any writebacks to be performed. - * @return The block to place the replacement in. - */ - SplitBlk* findReplacement(Addr addr, PacketList &writebacks); - - - /** - * Generate the tag from the given address. - * @param addr The address to get the tag from. - * @return The tag of the address. - */ - Addr extractTag(Addr addr) const; - - /** - * Calculate the set index from the address. - * @param addr The address to get the set from. - * @return The set index of the address. - */ - int extractSet(Addr addr) const - { - panic("should never call this!\n"); - M5_DUMMY_RETURN - } - - /** - * Get the block offset from an address. - * @param addr The address to get the offset of. - * @return The block offset. - */ - int extractBlkOffset(Addr addr) const - { - return (addr & blkMask); - } - - /** - * Align an address to the block size. - * @param addr the address to align. - * @return The block address. - */ - Addr blkAlign(Addr addr) const - { - return (addr & ~(Addr) (blkMask)); - } - - /** - * Regenerate the block address from the tag. - * @param tag The tag of the block. - * @param set The set of the block. - * @return The block address. - */ - Addr regenerateBlkAddr(Addr tag, int set) const; - - /** - * Return the hit latency. - * @return the hit latency. - */ - int getHitLatency() const - { - return hitLatency; - } - - /** - * Read the data out of the internal storage of the given cache block. - * @param blk The cache block to read. - * @param data The buffer to read the data into. - * @return The cache block's data. - */ - void readData(SplitBlk *blk, uint8_t *data) - { - std::memcpy(data, blk->data, blk->size); - } - - /** - * Write data into the internal storage of the given cache block. Since in - * Split does not store data differently this just needs to update the size. - * @param blk The cache block to write. - * @param data The data to write. - * @param size The number of bytes to write. - * @param writebacks A list for any writebacks to be performed. May be - * needed when writing to a compressed block. - */ - void writeData(SplitBlk *blk, uint8_t *data, int size, - PacketList & writebacks) - { - assert(size <= blkSize); - blk->size = size; - } - - /** - * Called at end of simulation to complete average block reference stats. - */ - virtual void cleanupRefs(); -}; - -#endif diff --git a/src/mem/cache/tags/split_blk.hh b/src/mem/cache/tags/split_blk.hh deleted file mode 100644 index d2efe08df..000000000 --- a/src/mem/cache/tags/split_blk.hh +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2004-2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Lisa Hsu - */ - -/** - * @file - * Declaration of partitioned tag store cache block class. - */ - -#ifndef __SPLIT_BLK_HH__ -#define __SPLIT_BLK_HH__ - -#include "mem/cache/blk.hh" // base class - -/** - * Split cache block. - */ -class SplitBlk : public CacheBlk { - public: - /** Has this block been touched? Used to aid calculation of warmup time. */ - bool isTouched; - /** Has this block been used after being brought in? (for LIFO partition) */ - bool isUsed; - /** is this blk a NIC block? (i.e. requested by the NIC) */ - bool isNIC; - /** timestamp of the arrival of this block into the cache */ - Tick ts; - /** the previous block in the LIFO partition (brought in before than me) */ - SplitBlk *prev; - /** the next block in the LIFO partition (brought in later than me) */ - SplitBlk *next; - /** which partition this block is in */ - int part; - - SplitBlk() - : isTouched(false), isUsed(false), isNIC(false), ts(0), prev(NULL), next(NULL), - part(0) - {} -}; - -#endif - diff --git a/src/mem/cache/tags/split_lifo.cc b/src/mem/cache/tags/split_lifo.cc deleted file mode 100644 index 3bdc7cae9..000000000 --- a/src/mem/cache/tags/split_lifo.cc +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright (c) 2004-2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Lisa Hsu - */ - -/** - * @file - * Definitions of LIFO tag store usable in a partitioned cache. - */ - -#include <string> - -#include "mem/cache/base.hh" -#include "base/intmath.hh" -#include "mem/cache/tags/split_lifo.hh" -#include "sim/core.hh" -#include "base/trace.hh" - -using namespace std; - -SplitBlk* -LIFOSet::findBlk(Addr tag) const -{ - for (SplitBlk *blk = firstIn; blk != NULL; blk = blk->next) { - if (blk->tag == tag && blk->isValid()) { - return blk; - } - } - return NULL; -} - -void -LIFOSet::moveToLastIn(SplitBlk *blk) -{ - if (blk == lastIn) - return; - - if (blk == firstIn) { - blk->next->prev = NULL; - } else { - blk->prev->next = blk->next; - blk->next->prev = blk->prev; - } - blk->next = NULL; - blk->prev = lastIn; - lastIn->next = blk; - - lastIn = blk; -} - -void -LIFOSet::moveToFirstIn(SplitBlk *blk) -{ - if (blk == firstIn) - return; - - if (blk == lastIn) { - blk->prev->next = NULL; - } else { - blk->next->prev = blk->prev; - blk->prev->next = blk->next; - } - - blk->prev = NULL; - blk->next = firstIn; - firstIn->prev = blk; - - firstIn = blk; -} - -// create and initialize a LIFO cache structure -SplitLIFO::SplitLIFO(int _blkSize, int _size, int _ways, int _hit_latency, bool two_Queue, int _part) : - blkSize(_blkSize), size(_size), numBlks(_size/_blkSize), numSets((_size/_ways)/_blkSize), ways(_ways), - hitLatency(_hit_latency), twoQueue(two_Queue), part(_part) -{ - if (!isPowerOf2(blkSize)) - fatal("cache block size (in bytes) must be a power of 2"); - if (!(hitLatency > 0)) - fatal("access latency in cycles must be at least on cycle"); - if (_ways == 0) - fatal("if instantiating a splitLIFO, needs non-zero size!"); - - - SplitBlk *blk; - int i, j, blkIndex; - - setShift = floorLog2(blkSize); - blkMask = blkSize - 1; - setMask = numSets - 1; - tagShift = setShift + floorLog2(numSets); - - warmedUp = false; - /** @todo Make warmup percentage a parameter. */ - warmupBound = size/blkSize; - - // allocate data blocks - blks = new SplitBlk[numBlks]; - sets = new LIFOSet[numSets]; - dataBlks = new uint8_t[size]; - -/* - // these start off point to same blk - top = &(blks[0]); - head = top; -*/ - - blkIndex = 0; - for (i=0; i < numSets; ++i) { - sets[i].ways = ways; - sets[i].lastIn = &blks[blkIndex]; - sets[i].firstIn = &blks[blkIndex + ways - 1]; - - /* 3 cases: if there is 1 way, if there are 2 ways, or if there are 3+. - in the case of 1 way, last in and first out point to the same blocks, - and the next and prev pointers need to be assigned specially. and so on - */ - /* deal with the first way */ - blk = &blks[blkIndex]; - blk->prev = &blks[blkIndex + 1]; - blk->next = NULL; - blk->data = &dataBlks[blkSize*blkIndex]; - blk->size = blkSize; - blk->part = part; - blk->set = i; - ++blkIndex; - - /* if there are "middle" ways, do them here */ - if (ways > 2) { - for (j=1; j < ways-1; ++j) { - blk = &blks[blkIndex]; - blk->data = &dataBlks[blkSize*blkIndex]; - blk->prev = &blks[blkIndex+1]; - blk->next = &blks[blkIndex-1]; - blk->data = &(dataBlks[blkSize*blkIndex]); - blk->size = blkSize; - blk->part = part; - blk->set = i; - ++blkIndex; - } - } - - /* do the final way here, depending on whether the final way is the only - way or not - */ - if (ways > 1) { - blk = &blks[blkIndex]; - blk->prev = NULL; - blk->next = &blks[blkIndex - 1]; - blk->data = &dataBlks[blkSize*blkIndex]; - blk->size = blkSize; - blk->part = part; - blk->set = i; - ++blkIndex; - } else { - blk->prev = NULL; - } - } - assert(blkIndex == numBlks); -} - -SplitLIFO::~SplitLIFO() -{ - delete [] blks; - delete [] sets; - delete [] dataBlks; -} - -void -SplitLIFO::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) - ; - - invalidations - .name(name + ".invalidations") - .desc("number of invalidations in this partition") - .precision(0) - ; -} - -// probe cache for presence of given block. -bool -SplitLIFO::probe(Addr addr) const -{ - Addr tag = extractTag(addr); - unsigned myset = extractSet(addr); - - SplitBlk* blk = sets[myset].findBlk(tag); - return (blk != NULL); -} - -SplitBlk* -SplitLIFO::findBlock(Addr addr, int &lat) -{ - Addr tag = extractTag(addr); - unsigned set = extractSet(addr); - SplitBlk *blk = sets[set].findBlk(tag); - - lat = hitLatency; - - if (blk) { - DPRINTF(Split, "Found LIFO blk %#x in set %d, with tag %#x\n", - addr, set, tag); - hits++; - - if (blk->whenReady > curTick && blk->whenReady - curTick > hitLatency) - lat = blk->whenReady - curTick; - blk->refCount +=1; - - if (twoQueue) { - blk->isUsed = true; - sets[set].moveToFirstIn(blk); - } else { - sets[set].moveToLastIn(blk); - } - } - - return blk; -} - - -SplitBlk* -SplitLIFO::findBlock(Addr addr) const -{ - Addr tag = extractTag(addr); - unsigned set = extractSet(addr); - SplitBlk *blk = sets[set].findBlk(tag); - - return blk; -} - -SplitBlk* -SplitLIFO::findReplacement(Addr addr, PacketList &writebacks) -{ - unsigned set = extractSet(addr); - - SplitBlk *firstIn = sets[set].firstIn; - SplitBlk *lastIn = sets[set].lastIn; - - SplitBlk *blk; - if (twoQueue && firstIn->isUsed) { - blk = firstIn; - blk->isUsed = false; - sets[set].moveToLastIn(blk); - } else { - int withValue = sets[set].withValue; - if (withValue == ways) { - blk = lastIn; - } else { - blk = &(sets[set].firstIn[ways - ++withValue]); - } - } - - DPRINTF(Split, "just assigned %#x addr into LIFO, replacing %#x status %#x\n", - addr, regenerateBlkAddr(blk->tag, set), blk->status); - if (blk->isValid()) { - replacements[0]++; - totalRefs += blk->refCount; - ++sampledRefs; - blk->refCount = 0; - } else { - tagsInUse++; - blk->isTouched = true; - if (!warmedUp && tagsInUse.value() >= warmupBound) { - warmedUp = true; - warmupCycle = curTick; - } - } - - misses++; - - return blk; -} - -void -SplitLIFO::invalidateBlk(SplitLIFO::BlkType *blk) -{ - if (blk) { - blk->status = 0; - blk->isTouched = false; - tagsInUse--; - invalidations++; - } -} - -void -SplitLIFO::cleanupRefs() -{ - for (int i = 0; i < numBlks; ++i) { - if (blks[i].isValid()) { - totalRefs += blks[i].refCount; - ++sampledRefs; - } - } -} diff --git a/src/mem/cache/tags/split_lifo.hh b/src/mem/cache/tags/split_lifo.hh deleted file mode 100644 index 0fd5f5c3c..000000000 --- a/src/mem/cache/tags/split_lifo.hh +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright (c) 2004-2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Lisa Hsu - */ - -/** - * @file - * Declaration of a LIFO tag store usable in a partitioned cache. - */ - -#ifndef __SPLIT_LIFO_HH__ -#define __SPLIT_LIFO_HH__ - -#include <cstring> -#include <list> - -#include "mem/cache/blk.hh" // base class -#include "mem/cache/tags/split_blk.hh" -#include "mem/packet.hh" // for inlined functions -#include "base/hashmap.hh" -#include <assert.h> -#include "mem/cache/tags/base.hh" - -class BaseCache; - -/** - * A LIFO set of cache blks - */ -class LIFOSet { - public: - /** the number of blocks in this set */ - int ways; - - /** Cache blocks in this set, maintained in LIFO order where - 0 = Last in (head) */ - SplitBlk *lastIn; - SplitBlk *firstIn; - - /** has the initial "filling" of this set finished? i.e., have you had - * 'ways' number of compulsory misses in this set yet? if withValue == ways, - * then yes. withValue is meant to be the number of blocks in the set that have - * gone through their first compulsory miss. - */ - int withValue; - - /** - * Find a block matching the tag in this set. - * @param asid The address space ID. - * @param tag the Tag you are looking for - * @return Pointer to the block, if found, NULL otherwise - */ - SplitBlk* findBlk(Addr tag) const; - - void moveToLastIn(SplitBlk *blk); - void moveToFirstIn(SplitBlk *blk); - - LIFOSet() - : ways(-1), lastIn(NULL), firstIn(NULL), withValue(0) - {} -}; - -/** - * A LIFO cache tag store. - */ -class SplitLIFO : public BaseTags -{ - public: - /** Typedef the block type used in this tag store. */ - typedef SplitBlk BlkType; - /** Typedef for a list of pointers to the local block class. */ - typedef std::list<SplitBlk*> BlkList; - protected: - /** The number of bytes in a block. */ - const int blkSize; - /** the size of the cache in bytes */ - const int size; - /** the number of blocks in the cache */ - const int numBlks; - /** the number of sets in the cache */ - const int numSets; - /** the number of ways in the cache */ - const int ways; - /** The hit latency. */ - const int hitLatency; - /** whether this is a "2 queue" replacement @sa moveToLastIn @sa moveToFirstIn */ - const bool twoQueue; - /** indicator for which partition this is */ - const int part; - - /** The cache blocks. */ - SplitBlk *blks; - /** The Cache sets */ - LIFOSet *sets; - /** The data blocks, 1 per cache block. */ - uint8_t *dataBlks; - - /** The amount to shift the address to get the set. */ - int setShift; - /** The amount to shift the address to get the tag. */ - int tagShift; - /** Mask out all bits that aren't part of the set index. */ - unsigned setMask; - /** Mask out all bits that aren't part of the block offset. */ - unsigned blkMask; - - - /** the number of hit in this partition */ - Stats::Scalar<> hits; - /** the number of blocks brought into this partition (i.e. misses) */ - Stats::Scalar<> misses; - /** the number of invalidations in this partition */ - Stats::Scalar<> invalidations; - -public: - /** - * Construct and initialize this tag store. - * @param _numSets The number of sets in the cache. - * @param _blkSize The number of bytes in a block. - * @param _assoc The associativity of the cache. - * @param _hit_latency The latency in cycles for a hit. - */ - SplitLIFO(int _blkSize, int _size, int _ways, int _hit_latency, bool twoQueue, int _part); - - /** - * Destructor - */ - virtual ~SplitLIFO(); - - /** - * Register the statistics for this object - * @param name The name to precede the stat - */ - void regStats(const std::string &name); - - /** - * Return the block size. - * @return the block size. - */ - int getBlockSize() - { - return blkSize; - } - - /** - * Return the subblock size. In the case of LIFO it is always the block - * size. - * @return The block size. - */ - int getSubBlockSize() - { - return blkSize; - } - - /** - * Search for the address in the cache. - * @param asid The address space ID. - * @param addr The address to find. - * @return True if the address is in the cache. - */ - bool probe( Addr addr) const; - - /** - * Invalidate the given block. - * @param blk The block to invalidate. - */ - void invalidateBlk(BlkType *blk); - - /** - * Finds the given address in the cache and update replacement data. - * Returns the access latency as a side effect. - * @param addr The address to find. - * @param asid The address space ID. - * @param lat The access latency. - * @return Pointer to the cache block if found. - */ - SplitBlk* findBlock(Addr addr, int &lat); - - /** - * Finds the given address in the cache, do not update replacement data. - * @param addr The address to find. - * @param asid The address space ID. - * @return Pointer to the cache block if found. - */ - SplitBlk* findBlock(Addr addr) const; - - /** - * Find a replacement block for the address provided. - * @param pkt The request to a find a replacement candidate for. - * @param writebacks List for any writebacks to be performed. - * @return The block to place the replacement in. - */ - SplitBlk* findReplacement(Addr addr, PacketList &writebacks); - - /** - * Generate the tag from the given address. - * @param addr The address to get the tag from. - * @return The tag of the address. - */ - Addr extractTag(Addr addr) const - { - return (addr >> tagShift); - } - - /** - * Calculate the set index from the address. - * @param addr The address to get the set from. - * @return The set index of the address. - */ - int extractSet(Addr addr) const - { - return ((addr >> setShift) & setMask); - } - - /** - * Get the block offset from an address. - * @param addr The address to get the offset of. - * @return The block offset. - */ - int extractBlkOffset(Addr addr) const - { - return (addr & blkMask); - } - - /** - * Align an address to the block size. - * @param addr the address to align. - * @return The block address. - */ - Addr blkAlign(Addr addr) const - { - return (addr & ~(Addr)blkMask); - } - - /** - * Regenerate the block address from the tag. - * @param tag The tag of the block. - * @param set The set of the block. - * @return The block address. - */ - Addr regenerateBlkAddr(Addr tag, unsigned set) const - { - return ((tag << tagShift) | ((Addr)set << setShift)); - } - - /** - * Return the hit latency. - * @return the hit latency. - */ - int getHitLatency() const - { - return hitLatency; - } - - /** - * Read the data out of the internal storage of the given cache block. - * @param blk The cache block to read. - * @param data The buffer to read the data into. - * @return The cache block's data. - */ - void readData(SplitBlk *blk, uint8_t *data) - { - std::memcpy(data, blk->data, blk->size); - } - - /** - * Write data into the internal storage of the given cache block. Since in - * LIFO does not store data differently this just needs to update the size. - * @param blk The cache block to write. - * @param data The data to write. - * @param size The number of bytes to write. - * @param writebacks A list for any writebacks to be performed. May be - * needed when writing to a compressed block. - */ - void writeData(SplitBlk *blk, uint8_t *data, int size, - PacketList & writebacks) - { - assert(size <= blkSize); - blk->size = size; - } - - /** - * Called at end of simulation to complete average block reference stats. - */ - virtual void cleanupRefs(); -}; - -#endif diff --git a/src/mem/cache/tags/split_lru.cc b/src/mem/cache/tags/split_lru.cc deleted file mode 100644 index 2b01b07cd..000000000 --- a/src/mem/cache/tags/split_lru.cc +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (c) 2004-2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Lisa 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; -} - - -void -SplitCacheSet::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 structure -SplitLRU::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; -} - -void -SplitLRU::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. -bool -SplitLRU::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; -} - -void -SplitLRU::invalidateBlk(SplitLRU::BlkType *blk) -{ - if (blk) { - blk->status = 0; - blk->isTouched = false; - tagsInUse--; - } -} - -void -SplitLRU::cleanupRefs() -{ - for (int i = 0; i < numSets*assoc; ++i) { - if (blks[i].isValid()) { - totalRefs += blks[i].refCount; - ++sampledRefs; - } - } -} diff --git a/src/mem/cache/tags/split_lru.hh b/src/mem/cache/tags/split_lru.hh deleted file mode 100644 index d41b6efa7..000000000 --- a/src/mem/cache/tags/split_lru.hh +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (c) 2004-2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Lisa Hsu - */ - -/** - * @file - * Declaration of a LRU tag store for a partitioned cache. - */ - -#ifndef __SPLIT_LRU_HH__ -#define __SPLIT_LRU_HH__ - -#include <cstring> -#include <list> - -#include "mem/cache/blk.hh" // base class -#include "mem/cache/tags/split_blk.hh" -#include "mem/packet.hh" // for inlined functions -#include <assert.h> -#include "mem/cache/tags/base.hh" - -class BaseCache; - -/** - * An associative set of cache blocks. - */ - -class SplitCacheSet -{ - public: - /** The associativity of this set. */ - int assoc; - - /** Cache blocks in this set, maintained in LRU order 0 = MRU. */ - SplitBlk **blks; - - /** - * Find a block matching the tag in this set. - * @param asid The address space ID. - * @param tag The Tag to find. - * @return Pointer to the block if found. - */ - SplitBlk* findBlk(Addr tag) const; - - /** - * Move the given block to the head of the list. - * @param blk The block to move. - */ - void moveToHead(SplitBlk *blk); -}; - -/** - * A LRU cache tag store. - */ -class SplitLRU : public BaseTags -{ - public: - /** Typedef the block type used in this tag store. */ - typedef SplitBlk BlkType; - /** Typedef for a list of pointers to the local block class. */ - typedef std::list<SplitBlk*> BlkList; - protected: - /** The number of sets in the cache. */ - const int numSets; - /** The number of bytes in a block. */ - const int blkSize; - /** The associativity of the cache. */ - const int assoc; - /** The hit latency. */ - const int hitLatency; - /** indicator for which partition this is */ - const int part; - - /** The cache sets. */ - SplitCacheSet *sets; - - /** The cache blocks. */ - SplitBlk *blks; - /** The data blocks, 1 per cache block. */ - uint8_t *dataBlks; - - /** The amount to shift the address to get the set. */ - int setShift; - /** The amount to shift the address to get the tag. */ - int tagShift; - /** Mask out all bits that aren't part of the set index. */ - unsigned setMask; - /** Mask out all bits that aren't part of the block offset. */ - unsigned blkMask; - - /** number of hits in this partition */ - Stats::Scalar<> hits; - /** number of blocks brought into this partition (i.e. misses) */ - Stats::Scalar<> misses; - -public: - /** - * Construct and initialize this tag store. - * @param _numSets The number of sets in the cache. - * @param _blkSize The number of bytes in a block. - * @param _assoc The associativity of the cache. - * @param _hit_latency The latency in cycles for a hit. - */ - SplitLRU(int _numSets, int _blkSize, int _assoc, int _hit_latency, int _part); - - /** - * Destructor - */ - virtual ~SplitLRU(); - - /** - * Register the statistics for this object - * @param name The name to precede the stat - */ - void regStats(const std::string &name); - - /** - * Return the block size. - * @return the block size. - */ - int getBlockSize() - { - return blkSize; - } - - /** - * Return the subblock size. In the case of LRU it is always the block - * size. - * @return The block size. - */ - int getSubBlockSize() - { - return blkSize; - } - - /** - * Search for the address in the cache. - * @param asid The address space ID. - * @param addr The address to find. - * @return True if the address is in the cache. - */ - bool probe(Addr addr) const; - - /** - * Invalidate the given block. - * @param blk The block to invalidate. - */ - void invalidateBlk(BlkType *blk); - - /** - * Finds the given address in the cache and update replacement data. - * Returns the access latency as a side effect. - * @param addr The address to find. - * @param asid The address space ID. - * @param lat The access latency. - * @return Pointer to the cache block if found. - */ - SplitBlk* findBlock(Addr addr, int &lat); - - /** - * Finds the given address in the cache, do not update replacement data. - * @param addr The address to find. - * @param asid The address space ID. - * @return Pointer to the cache block if found. - */ - SplitBlk* findBlock(Addr addr) const; - - /** - * Find a replacement block for the address provided. - * @param pkt The request to a find a replacement candidate for. - * @param writebacks List for any writebacks to be performed. - * @return The block to place the replacement in. - */ - SplitBlk* findReplacement(Addr addr, PacketList &writebacks); - - /** - * Generate the tag from the given address. - * @param addr The address to get the tag from. - * @return The tag of the address. - */ - Addr extractTag(Addr addr) const - { - return (addr >> tagShift); - } - - /** - * Calculate the set index from the address. - * @param addr The address to get the set from. - * @return The set index of the address. - */ - int extractSet(Addr addr) const - { - return ((addr >> setShift) & setMask); - } - - /** - * Get the block offset from an address. - * @param addr The address to get the offset of. - * @return The block offset. - */ - int extractBlkOffset(Addr addr) const - { - return (addr & blkMask); - } - - /** - * Align an address to the block size. - * @param addr the address to align. - * @return The block address. - */ - Addr blkAlign(Addr addr) const - { - return (addr & ~(Addr)blkMask); - } - - /** - * Regenerate the block address from the tag. - * @param tag The tag of the block. - * @param set The set of the block. - * @return The block address. - */ - Addr regenerateBlkAddr(Addr tag, unsigned set) const - { - return ((tag << tagShift) | ((Addr)set << setShift)); - } - - /** - * Return the hit latency. - * @return the hit latency. - */ - int getHitLatency() const - { - return hitLatency; - } - - /** - * Read the data out of the internal storage of the given cache block. - * @param blk The cache block to read. - * @param data The buffer to read the data into. - * @return The cache block's data. - */ - void readData(SplitBlk *blk, uint8_t *data) - { - std::memcpy(data, blk->data, blk->size); - } - - /** - * Write data into the internal storage of the given cache block. Since in - * LRU does not store data differently this just needs to update the size. - * @param blk The cache block to write. - * @param data The data to write. - * @param size The number of bytes to write. - * @param writebacks A list for any writebacks to be performed. May be - * needed when writing to a compressed block. - */ - void writeData(SplitBlk *blk, uint8_t *data, int size, - PacketList & writebacks) - { - assert(size <= blkSize); - blk->size = size; - } - - /** - * Called at end of simulation to complete average block reference stats. - */ - virtual void cleanupRefs(); -}; - -#endif diff --git a/src/mem/config/cache.hh b/src/mem/config/cache.hh index 24da04021..946ed444f 100644 --- a/src/mem/config/cache.hh +++ b/src/mem/config/cache.hh @@ -36,7 +36,4 @@ */ #define USE_CACHE_LRU 1 #define USE_CACHE_FALRU 1 -// #define USE_CACHE_SPLIT 1 -// #define USE_CACHE_SPLIT_LIFO 1 #define USE_CACHE_IIC 1 - |