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)")
"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")
#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"
#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); \
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; \
#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
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
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')
+++ /dev/null
-/*
- * 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);
-*/
-}
-
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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
-
+++ /dev/null
-/*
- * 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;
- }
- }
-}
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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;
- }
- }
-}
+++ /dev/null
-/*
- * 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
*/
#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
-