hit_latency = Param.Cycles("The hit latency for this cache")
response_latency = Param.Cycles(
"Additional cache latency for the return path to core on a miss");
- hash_delay = Param.Cycles(1, "time in cycles of hash access")
max_miss_count = Param.Counter(0,
"number of misses to handle before calling exit")
mshrs = Param.Int("number of MSHRs (max outstanding requests)")
- prioritizeRequests = Param.Bool(False,
- "always service demand misses first")
- repl = Param.Repl(NULL, "replacement policy")
size = Param.MemorySize("capacity in bytes")
forward_snoops = Param.Bool(True,
"forward snoops from mem side to cpu side")
is_top_level = Param.Bool(False, "Is this cache at the top level (e.g. L1)")
- subblock_size = Param.Int(0,
- "Size of subblock in IIC used for compression")
tgts_per_mshr = Param.Int("max number of accesses per MSHR")
- trace_addr = Param.Addr(0, "address to trace")
two_queue = Param.Bool(False,
"whether the lifo should have two queue replacement")
write_buffers = Param.Int(8, "number of write buffers")
#include "mem/cache/tags/fa_lru.hh"
#endif
-#if defined(USE_CACHE_IIC)
-#include "mem/cache/tags/iic.hh"
-#endif
-
using namespace std;
#define BUILD_LRU_CACHE BUILD_CACHE_PANIC("lru cache")
#endif
-#if defined(USE_CACHE_IIC)
-#define BUILD_IIC_CACHE do { \
- IIC *tags = new IIC(iic_params); \
- BUILD_CACHE(IIC, tags); \
- } while (0)
-#else
-#define BUILD_IIC_CACHE BUILD_CACHE_PANIC("iic")
-#endif
-
-#define BUILD_CACHES do { \
- if (repl == NULL) { \
- if (numSets == 1) { \
- BUILD_FALRU_CACHE; \
- } else { \
- BUILD_LRU_CACHE; \
- } \
- } else { \
- BUILD_IIC_CACHE; \
- } \
- } while (0)
-
BaseCache *
BaseCacheParams::create()
{
int numSets = size / (assoc * block_size);
- if (subblock_size == 0) {
- subblock_size = block_size;
- }
-#if defined(USE_CACHE_IIC)
- // Build IIC params
- IIC::Params iic_params;
- iic_params.size = size;
- iic_params.numSets = numSets;
- iic_params.blkSize = block_size;
- iic_params.assoc = assoc;
- iic_params.hashDelay = hash_delay;
- iic_params.hitLatency = hit_latency;
- iic_params.rp = repl;
- iic_params.subblockSize = subblock_size;
-#else
- const void *repl = NULL;
-#endif
+ if (numSets == 1) {
+ BUILD_FALRU_CACHE;
+ } else {
+ BUILD_LRU_CACHE;
+ }
- BUILD_CACHES;
return NULL;
}
#include "mem/cache/tags/fa_lru.hh"
#endif
-#if defined(USE_CACHE_IIC)
-#include "mem/cache/tags/iic.hh"
-#endif
-
#include "mem/cache/cache_impl.hh"
// Template Instantiations
template class Cache<FALRU>;
#endif
-#if defined(USE_CACHE_IIC)
-template class Cache<IIC>;
-#endif
-
#if defined(USE_CACHE_LRU)
template class Cache<LRU>;
#endif
Source('base.cc')
Source('fa_lru.cc')
-Source('iic.cc')
Source('lru.cc')
Source('cacheset.cc')
-
-SimObject('iic_repl/Repl.py')
-Source('iic_repl/gen.cc')
-
-DebugFlag('IIC')
-DebugFlag('IICMore')
+++ /dev/null
-/*
- * Copyright (c) 2002-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: Erik Hallnor
- */
-
-/**
- * @file
- * Definitions of the Indirect Index Cache tagstore.
- */
-
-#include <algorithm>
-#include <cmath>
-#include <string>
-#include <vector>
-
-#include "base/intmath.hh"
-#include "base/trace.hh"
-#include "debug/Cache.hh"
-#include "debug/IIC.hh"
-#include "debug/IICMore.hh"
-#include "mem/cache/tags/iic.hh"
-#include "mem/cache/base.hh"
-#include "sim/core.hh"
-
-using namespace std;
-
-/** Track the number of accesses to each cache set. */
-#define PROFILE_IIC 1
-
-IIC::IIC(IIC::Params ¶ms) :
- hashSets(params.numSets), blkSize(params.blkSize), assoc(params.assoc),
- hitLatency(params.hitLatency), subSize(params.subblockSize),
- numSub(blkSize/subSize),
- trivialSize((floorLog2(params.size/subSize)*numSub)/8),
- tagShift(floorLog2(blkSize)), blkMask(blkSize - 1),
- subShift(floorLog2(subSize)), subMask(numSub - 1),
- hashDelay(params.hashDelay),
- numTags(hashSets * assoc + params.size/blkSize -1),
- numSecondary(params.size/blkSize),
- tagNull(numTags),
- primaryBound(hashSets * assoc)
-{
- // Check parameters
- if (blkSize < 4 || !isPowerOf2(blkSize)) {
- fatal("Block size must be at least 4 and a power of 2");
- }
- if (hashSets <= 0 || !isPowerOf2(hashSets)) {
- fatal("# of hashsets 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");
- }
- if (numSub*subSize != blkSize) {
- fatal("blocksize must be evenly divisible by subblock size");
- }
-
- // debug stuff
- freeSecond = numSecondary;
-
- warmedUp = false;
- warmupBound = params.size/blkSize;
- numBlocks = params.size/subSize;
-
- // Replacement Policy Initialization
- repl = params.rp;
- repl->setIIC(this);
-
- //last_miss_time = 0
-
- // allocate data reference counters
- dataReferenceCount = new int[numBlocks];
- memset(dataReferenceCount, 0, numBlocks*sizeof(int));
-
- // Allocate storage for both internal data and block fast access data.
- // We allocate it as one large chunk to reduce overhead and to make
- // deletion easier.
- unsigned data_index = 0;
- dataStore = new uint8_t[(numBlocks + numTags) * blkSize];
- dataBlks = new uint8_t*[numBlocks];
- for (unsigned i = 0; i < numBlocks; ++i) {
- dataBlks[i] = &dataStore[data_index];
- freeDataBlock(i);
- data_index += subSize;
- }
-
- assert(data_index == numBlocks * subSize);
-
- // allocate and init tag store
- tagStore = new IICTag[numTags];
-
- unsigned blkIndex = 0;
- // allocate and init sets
- sets = new IICSet[hashSets];
- for (unsigned i = 0; i < hashSets; ++i) {
- sets[i].assoc = assoc;
- sets[i].tags = new IICTag*[assoc];
- sets[i].chain_ptr = tagNull;
-
- for (unsigned j = 0; j < assoc; ++j) {
- IICTag *tag = &tagStore[blkIndex++];
- tag->chain_ptr = tagNull;
- tag->data_ptr.resize(numSub);
- tag->size = blkSize;
- tag->trivialData = new uint8_t[trivialSize];
- tag->numData = 0;
- sets[i].tags[j] = tag;
- tag->set = i;
- tag->data = &dataStore[data_index];
- data_index += blkSize;
- }
- }
-
- assert(blkIndex == primaryBound);
-
- for (unsigned i = primaryBound; i < tagNull; i++) {
- tagStore[i].chain_ptr = i+1;
- //setup data ptrs to subblocks
- tagStore[i].data_ptr.resize(numSub);
- tagStore[i].size = blkSize;
- tagStore[i].trivialData = new uint8_t[trivialSize];
- tagStore[i].numData = 0;
- tagStore[i].set = 0;
- tagStore[i].data = &dataStore[data_index];
- data_index += blkSize;
- }
- freelist = primaryBound;
-}
-
-IIC::~IIC()
-{
- delete [] dataReferenceCount;
- delete [] dataStore;
- delete [] tagStore;
- delete [] sets;
- delete [] dataBlks;
-}
-
-/* register cache stats */
-void
-IIC::regStats(const string &name)
-{
- using namespace Stats;
-
- BaseTags::regStats(name);
-
- hitHashDepth.init(0, 20, 1);
- missHashDepth.init(0, 20, 1);
- setAccess.init(0, hashSets, 1);
-
- /** IIC Statistics */
- hitHashDepth
- .name(name + ".hit_hash_depth_dist")
- .desc("Dist. of Hash lookup depths")
- .flags(pdf)
- ;
-
- missHashDepth
- .name(name + ".miss_hash_depth_dist")
- .desc("Dist. of Hash lookup depths")
- .flags(pdf)
- ;
-
- repl->regStatsWithSuffix(name);
-
- if (PROFILE_IIC)
- setAccess
- .name(name + ".set_access_dist")
- .desc("Dist. of Accesses across sets")
- .flags(pdf)
- ;
-
- missDepthTotal
- .name(name + ".miss_depth_total")
- .desc("Total of miss depths")
- ;
-
- hashMiss
- .name(name + ".hash_miss")
- .desc("Total of misses in hash table")
- ;
-
- hitDepthTotal
- .name(name + ".hit_depth_total")
- .desc("Total of hit depths")
- ;
-
- hashHit
- .name(name + ".hash_hit")
- .desc("Total of hites in hash table")
- ;
-}
-
-
-IICTag*
-IIC::accessBlock(Addr addr, Cycles &lat, int context_src)
-{
- Addr tag = extractTag(addr);
- unsigned set = hash(addr);
- Cycles set_lat;
-
- unsigned long chain_ptr = tagNull;
-
- if (PROFILE_IIC)
- setAccess.sample(set);
-
- IICTag *tag_ptr = sets[set].findTag(tag, chain_ptr);
- set_lat = Cycles(1);
- if (tag_ptr == NULL && chain_ptr != tagNull) {
- int secondary_depth;
- tag_ptr = secondaryChain(tag, chain_ptr, &secondary_depth);
- set_lat += Cycles(secondary_depth);
- // set depth for statistics fix this later!!! egh
- sets[set].depth = set_lat;
-
- if (tag_ptr != NULL) {
- /* need to move tag into primary table */
- // need to preserve chain: fix this egh
- sets[set].tags[assoc-1]->chain_ptr = tag_ptr->chain_ptr;
- tagSwap(tag_ptr - tagStore, sets[set].tags[assoc-1] - tagStore);
- tag_ptr = sets[set].findTag(tag, chain_ptr);
- assert(tag_ptr!=NULL);
- }
-
- }
- set_lat = Cycles(set_lat * hashDelay + hitLatency);
- if (tag_ptr != NULL) {
- // IIC replacement: if this is not the first element of
- // list, reorder
- sets[set].moveToHead(tag_ptr);
-
- hitHashDepth.sample(sets[set].depth);
- hashHit++;
- hitDepthTotal += sets[set].depth;
- tag_ptr->status |= BlkReferenced;
- lat = set_lat;
- if (tag_ptr->whenReady > curTick() &&
- cache->ticksToCycles(tag_ptr->whenReady - curTick()) > set_lat) {
- lat = cache->ticksToCycles(tag_ptr->whenReady - curTick());
- }
-
- tag_ptr->refCount += 1;
- }
- else {
- // fall through: cache block not found, not a hit...
- missHashDepth.sample(sets[set].depth);
- hashMiss++;
- missDepthTotal += sets[set].depth;
- lat = set_lat;
- }
- return tag_ptr;
-}
-
-
-IICTag*
-IIC::findBlock(Addr addr) const
-{
- Addr tag = extractTag(addr);
- unsigned set = hash(addr);
-
- unsigned long chain_ptr = tagNull;
-
- IICTag *tag_ptr = sets[set].findTag(tag, chain_ptr);
- if (tag_ptr == NULL && chain_ptr != tagNull) {
- int secondary_depth;
- tag_ptr = secondaryChain(tag, chain_ptr, &secondary_depth);
- }
- return tag_ptr;
-}
-
-
-IICTag*
-IIC::findVictim(Addr addr, PacketList &writebacks)
-{
- DPRINTF(IIC, "Finding Replacement for %x\n", addr);
- unsigned set = hash(addr);
- IICTag *tag_ptr;
- unsigned long *tmp_data = new unsigned long[numSub];
-
- // Get a enough subblocks for a full cache line
- for (unsigned i = 0; i < numSub; ++i){
- tmp_data[i] = getFreeDataBlock(writebacks);
- assert(dataReferenceCount[tmp_data[i]]==0);
- }
-
- tag_ptr = getFreeTag(set, writebacks);
-
- tag_ptr->set = set;
- for (unsigned i = 0; i < numSub; ++i) {
- tag_ptr->data_ptr[i] = tmp_data[i];
- dataReferenceCount[tag_ptr->data_ptr[i]]++;
- }
- tag_ptr->numData = numSub;
- assert(tag_ptr - tagStore < primaryBound); // make sure it is in primary
- tag_ptr->chain_ptr = tagNull;
- sets[set].moveToHead(tag_ptr);
- delete [] tmp_data;
-
- list<unsigned long> tag_indexes;
- repl->doAdvance(tag_indexes);
-/*
- while (!tag_indexes.empty()) {
- if (!tagStore[tag_indexes.front()].isCompressed()) {
- compress_blocks.push_back(&tagStore[tag_indexes.front()]);
- }
- tag_indexes.pop_front();
- }
-*/
-
- tag_ptr->re = (void*)repl->add(tag_ptr-tagStore);
-
- return tag_ptr;
-}
-
-void
-IIC::insertBlock(Addr addr, BlkType* blk, int context_src)
-{
-}
-
-void
-IIC::freeReplacementBlock(PacketList & writebacks)
-{
- IICTag *tag_ptr;
- unsigned long data_ptr;
- /* consult replacement policy */
- tag_ptr = &tagStore[repl->getRepl()];
- assert(tag_ptr != NULL);
- assert(tag_ptr->isValid());
-
- DPRINTF(Cache, "Replacing %x in IIC: %s\n",
- regenerateBlkAddr(tag_ptr->tag,0),
- tag_ptr->isDirty() ? "writeback" : "clean");
- /* write back replaced block data */
- replacements[0]++;
- totalRefs += tag_ptr->refCount;
- ++sampledRefs;
- tag_ptr->refCount = 0;
-
- if (tag_ptr->isDirty()) {
-/* PacketPtr writeback =
- buildWritebackReq(regenerateBlkAddr(tag_ptr->tag, 0),
- tag_ptr->req->asid, tag_ptr->xc, blkSize,
- tag_ptr->data,
- tag_ptr->size);
-*/
- Request *writebackReq = new Request(regenerateBlkAddr(tag_ptr->tag, 0),
- blkSize, 0, Request::wbMasterId);
- PacketPtr writeback = new Packet(writebackReq, MemCmd::Writeback);
- writeback->allocate();
- memcpy(writeback->getPtr<uint8_t>(), tag_ptr->data, blkSize);
-
- writebacks.push_back(writeback);
- }
-
- // free the data blocks
- for (int i = 0; i < tag_ptr->numData; ++i) {
- data_ptr = tag_ptr->data_ptr[i];
- assert(dataReferenceCount[data_ptr]>0);
- if (--dataReferenceCount[data_ptr] == 0) {
- freeDataBlock(data_ptr);
- }
- }
- freeTag(tag_ptr);
-}
-
-unsigned long
-IIC::getFreeDataBlock(PacketList & writebacks)
-{
- unsigned long data_ptr;
-
- /* find data block */
- while (blkFreelist.empty()) {
- freeReplacementBlock(writebacks);
- }
-
- data_ptr = blkFreelist.front();
- blkFreelist.pop_front();
- DPRINTF(IICMore,"Found free data at %d\n",data_ptr);
- return data_ptr;
-}
-
-
-
-IICTag*
-IIC::getFreeTag(int set, PacketList & writebacks)
-{
- unsigned long tag_index;
- IICTag *tag_ptr;
- // Add new tag
- tag_ptr = sets[set].findFree();
- // if no free in primary, and secondary exists
- if (!tag_ptr && numSecondary) {
- // need to spill a tag into secondary storage
- while (freelist == tagNull) {
- // get replacements until one is in secondary
- freeReplacementBlock(writebacks);
- }
-
- tag_index = freelist;
- freelist = tagStore[freelist].chain_ptr;
- freeSecond--;
-
- assert(tag_index != tagNull);
- tagSwap(tag_index, sets[set].tags[assoc-1] - tagStore);
- tagStore[tag_index].chain_ptr = sets[set].chain_ptr;
- sets[set].chain_ptr = tag_index;
-
- tag_ptr = sets[set].tags[assoc-1];
- }
- DPRINTF(IICMore,"Found free tag at %d\n",tag_ptr - tagStore);
- tagsInUse++;
- if (!warmedUp && tagsInUse.value() >= warmupBound) {
- warmedUp = true;
- warmupCycle = curTick();
- }
-
- return tag_ptr;
-}
-
-void
-IIC::freeTag(IICTag *tag_ptr)
-{
- unsigned long tag_index, tmp_index;
- // Fix tag_ptr
- if (tag_ptr) {
- // we have a tag to clear
- DPRINTF(IICMore,"Freeing Tag for %x\n",
- regenerateBlkAddr(tag_ptr->tag,0));
- tagsInUse--;
- tag_ptr->status = 0;
- tag_ptr->numData = 0;
- tag_ptr->re = NULL;
- tag_index = tag_ptr - tagStore;
- if (tag_index >= primaryBound) {
- // tag_ptr points to secondary store
- assert(tag_index < tagNull); // remove this?? egh
- if (tag_ptr->chain_ptr == tagNull) {
- // need to fix chain list
- unsigned tmp_set = hash(tag_ptr->tag << tagShift);
- if (sets[tmp_set].chain_ptr == tag_index) {
- sets[tmp_set].chain_ptr = tagNull;
- } else {
- tmp_index = sets[tmp_set].chain_ptr;
- while (tmp_index != tagNull
- && tagStore[tmp_index].chain_ptr != tag_index) {
- tmp_index = tagStore[tmp_index].chain_ptr;
- }
- assert(tmp_index != tagNull);
- tagStore[tmp_index].chain_ptr = tagNull;
- }
- tag_ptr->chain_ptr = freelist;
- freelist = tag_index;
- freeSecond++;
- } else {
- // copy next chained entry to this tag location
- tmp_index = tag_ptr->chain_ptr;
- tagSwap(tmp_index, tag_index);
- tagStore[tmp_index].chain_ptr = freelist;
- freelist = tmp_index;
- freeSecond++;
- }
- } else {
- // tag_ptr in primary hash table
- assert(tag_index < primaryBound);
- tag_ptr->status = 0;
- unsigned tmp_set = hash(tag_ptr->tag << tagShift);
- if (sets[tmp_set].chain_ptr != tagNull) { // collapse chain
- tmp_index = sets[tmp_set].chain_ptr;
- tagSwap(tag_index, tmp_index);
- tagStore[tmp_index].chain_ptr = freelist;
- freelist = tmp_index;
- freeSecond++;
- sets[tmp_set].chain_ptr = tag_ptr->chain_ptr;
- sets[tmp_set].moveToTail(tag_ptr);
- }
- }
- }
-}
-
-void
-IIC::freeDataBlock(unsigned long data_ptr)
-{
- assert(dataReferenceCount[data_ptr] == 0);
- DPRINTF(IICMore, "Freeing data at %d\n", data_ptr);
- blkFreelist.push_front(data_ptr);
-}
-
-/** Use a simple modulo hash. */
-#define SIMPLE_HASH 0
-
-unsigned
-IIC::hash(Addr addr) const {
-#if SIMPLE_HASH
- return extractTag(addr) % iic_hash_size;
-#else
- Addr tag, mask, x, y;
- tag = extractTag(addr);
- mask = hashSets-1; /* assumes iic_hash_size is a power of 2 */
- x = tag & mask;
- y = (tag >> (int)(::log((double)hashSets)/::log((double)2))) & mask;
- assert (x < hashSets && y < hashSets);
- return x ^ y;
-#endif
-}
-
-
-void
-IICSet::moveToHead(IICTag *tag)
-{
- if (tags[0] == tag)
- 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;
- IICTag *next = tag;
-
- do {
- assert(i < assoc);
- // swap blks[i] and next
- IICTag *tmp = tags[i];
- tags[i] = next;
- next = tmp;
- ++i;
- } while (next != tag);
-}
-
-void
-IICSet::moveToTail(IICTag *tag)
-{
- if (tags[assoc-1] == tag)
- 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 = assoc - 1;
- IICTag *next = tag;
-
- do {
- assert(i >= 0);
- // swap blks[i] and next
- IICTag *tmp = tags[i];
- tags[i] = next;
- next = tmp;
- --i;
- } while (next != tag);
-}
-
-void
-IIC::tagSwap(unsigned long index1, unsigned long index2)
-{
- DPRINTF(IIC,"Swapping tag[%d]=%x for tag[%d]=%x\n",index1,
- tagStore[index1].tag<<tagShift, index2,
- tagStore[index2].tag<<tagShift);
- IICTag tmp_tag;
- tmp_tag = tagStore[index1];
- tagStore[index1] = tagStore[index2];
- tagStore[index2] = tmp_tag;
- if (tagStore[index1].isValid())
- repl->fixTag(tagStore[index1].re, index2, index1);
- if (tagStore[index2].isValid())
- repl->fixTag(tagStore[index2].re, index1, index2);
-}
-
-
-IICTag *
-IIC::secondaryChain(Addr tag, unsigned long chain_ptr,
- int *_depth) const
-{
- int depth = 0;
- while (chain_ptr != tagNull) {
- DPRINTF(IIC,"Searching secondary at %d for %x\n", chain_ptr,
- tag<<tagShift);
- if (tagStore[chain_ptr].tag == tag &&
- (tagStore[chain_ptr].isValid())) {
- *_depth = depth;
- return &tagStore[chain_ptr];
- }
- depth++;
- chain_ptr = tagStore[chain_ptr].chain_ptr;
- }
- *_depth = depth;
- return NULL;
-}
-
-void
-IIC::invalidate(IIC::BlkType *tag_ptr)
-{
- if (tag_ptr) {
- for (int i = 0; i < tag_ptr->numData; ++i) {
- dataReferenceCount[tag_ptr->data_ptr[i]]--;
- if (dataReferenceCount[tag_ptr->data_ptr[i]] == 0) {
- freeDataBlock(tag_ptr->data_ptr[i]);
- }
- }
- repl->removeEntry(tag_ptr->re);
- freeTag(tag_ptr);
- }
-}
-
-void
-IIC::clearLocks()
-{
- for (int i = 0; i < numTags; i++){
- tagStore[i].clearLoadLocks();
- }
-}
-
-void
-IIC::cleanupRefs()
-{
- for (unsigned i = 0; i < numTags; ++i) {
- if (tagStore[i].isValid()) {
- totalRefs += tagStore[i].refCount;
- ++sampledRefs;
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2012 ARM Limited
- * All rights reserved.
- *
- * The license below extends only to copyright in the software and shall
- * not be construed as granting a license to any other intellectual
- * property including but not limited to intellectual property relating
- * to a hardware implementation of the functionality of the software
- * licensed hereunder. You may use the software subject to the license
- * terms below provided that you ensure that this notice is replicated
- * unmodified and in its entirety in all distributions of the software,
- * modified or unmodified, in source code or in binary form.
- *
- * Copyright (c) 2002-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: Erik Hallnor
- */
-
-/**
- * @file
- * Declaration of the Indirect Index Cache (IIC) tags store.
- */
-
-#ifndef __IIC_HH__
-#define __IIC_HH__
-
-#include <list>
-#include <vector>
-
-#include "base/statistics.hh"
-#include "mem/cache/tags/iic_repl/repl.hh"
-#include "mem/cache/tags/base.hh"
-#include "mem/cache/blk.hh"
-#include "mem/packet.hh"
-
-class BaseCache; // Forward declaration
-
-/**
- * IIC cache blk.
- */
-class IICTag : public CacheBlk
-{
- public:
- /**
- * Copy the contents of the given IICTag into this one.
- * @param rhs The tag to copy.
- * @return const reference to this tag.
- */
- const IICTag& operator=(const IICTag& rhs)
- {
- CacheBlk::operator=(rhs);
- chain_ptr = rhs.chain_ptr;
- re = rhs.re;
- set = rhs.set;
- trivialData = rhs.trivialData;
- numData = rhs.numData;
- data_ptr.clear();
- for (int i = 0; i < rhs.numData; ++i) {
- data_ptr.push_back(rhs.data_ptr[i]);
- }
- return *this;
- }
-
- /** Hash chain pointer into secondary store. */
- unsigned long chain_ptr;
- /** Data array pointers for each subblock. */
- std::vector<unsigned long> data_ptr;
- /** Replacement Entry pointer. */
- void *re;
- /**
- * An array to store small compressed data. Conceputally the same size
- * as the unsused data array pointers.
- */
- uint8_t *trivialData;
- /**
- * The number of allocated subblocks.
- */
- int numData;
-};
-
-/**
- * A hash set for the IIC primary lookup table.
- */
-class IICSet{
- public:
- /** The associativity of the primary table. */
- int assoc;
-
- /** The number of hash chains followed when finding the last block. */
- int depth;
- /** The current number of blocks on the chain. */
- int size;
-
- /** Tag pointer into the secondary tag storage. */
- unsigned long chain_ptr;
-
- /** The LRU list of the primary table. MRU is at 0 index. */
- IICTag ** tags;
-
- /**
- * Find the addr in this set, return the chain pointer to the secondary if
- * it isn't found.
- * @param asid The address space ID.
- * @param tag The address to find.
- * @param chain_ptr The chain pointer to start the search of the secondary
- * @return Pointer to the tag, NULL if not found.
- */
- IICTag* findTag( Addr tag, unsigned long &chain_ptr)
- {
- depth = 1;
- for (int i = 0; i < assoc; ++i) {
- if (tags[i]->tag == tag && tags[i]->isValid()) {
- return tags[i];
- }
- }
- chain_ptr = this->chain_ptr;
- return 0;
- }
-
- /**
- * Find an usused tag in this set.
- * @return Pointer to the unused tag, NULL if none are free.
- */
- IICTag* findFree()
- {
- for (int i = 0; i < assoc; ++i) {
- if (!tags[i]->isValid()) {
- return tags[i];
- }
- }
- return 0;
- }
-
- /**
- * Move a tag to the head of the LRU list
- * @param tag The tag to move.
- */
- void moveToHead(IICTag *tag);
-
- /**
- * Move a tag to the tail (LRU) of the LRU list
- * @param tag The tag to move.
- */
- void moveToTail(IICTag *tag);
-};
-
-/**
- * The IIC tag store. This is a hardware-realizable, fully-associative tag
- * store that uses software replacement, e.g. Gen.
- */
-class IIC : public BaseTags
-{
- public:
- /** Typedef of the block type used in this class. */
- typedef IICTag BlkType;
- /** Typedef for list of pointers to the local block type. */
- typedef std::list<IICTag*> BlkList;
-
- protected:
- /** The number of set in the primary table. */
- const unsigned hashSets;
- /** The block size in bytes. */
- const unsigned blkSize;
- /** The associativity of the primary table. */
- const unsigned assoc;
- /** The base hit latency. */
- const Cycles hitLatency;
- /** The subblock size, used for compression. */
- const unsigned subSize;
-
- /** The number of subblocks */
- const unsigned numSub;
- /** The number of bytes used by data pointers */
- const unsigned trivialSize;
-
- /** The amount to shift address to get the tag. */
- const unsigned tagShift;
- /** The mask to get block offset bits. */
- const unsigned blkMask;
-
- /** The amount to shift to get the subblock number. */
- const unsigned subShift;
- /** The mask to get the correct subblock number. */
- const unsigned subMask;
-
- /** The latency of a hash lookup. */
- const Cycles hashDelay;
- /** The total number of tags in primary and secondary. */
- const unsigned numTags;
- /** The number of tags in the secondary tag store. */
- const unsigned numSecondary;
-
- /** The Null tag pointer. */
- const unsigned tagNull;
- /** The last tag in the primary table. */
- const unsigned primaryBound;
-
- /** All of the tags */
- IICTag *tagStore;
- /**
- * Pointer to the head of the secondary freelist (maintained with chain
- * pointers.
- */
- unsigned long freelist;
- /**
- * The data block freelist.
- */
- std::list<unsigned long> blkFreelist;
-
- /** The primary table. */
- IICSet *sets;
-
- /** The replacement policy. */
- Repl *repl;
-
- /** An array of data reference counters. */
- int *dataReferenceCount;
-
- /** The data blocks. */
- uint8_t *dataStore;
-
- /** Storage for the fast access data of each cache block. */
- uint8_t **dataBlks;
-
- /**
- * Count of the current number of free secondary tags.
- * Used for debugging.
- */
- int freeSecond;
-
- // IIC Statistics
- /**
- * @addtogroup IICStatistics IIC Statistics
- * @{
- */
-
- /** Hash hit depth of cache hits. */
- Stats::Distribution hitHashDepth;
- /** Hash depth for cache misses. */
- Stats::Distribution missHashDepth;
- /** Count of accesses to each hash set. */
- Stats::Distribution setAccess;
-
- /** The total hash depth for every miss. */
- Stats::Scalar missDepthTotal;
- /** The total hash depth for all hits. */
- Stats::Scalar hitDepthTotal;
- /** The number of hash misses. */
- Stats::Scalar hashMiss;
- /** The number of hash hits. */
- Stats::Scalar hashHit;
- /** @} */
-
- public:
- /**
- * Collection of parameters for the IIC.
- */
- class Params {
- public:
- /** The size in bytes of the cache. */
- unsigned size;
- /** The number of sets in the primary table. */
- unsigned numSets;
- /** The block size in bytes. */
- unsigned blkSize;
- /** The associativity of the primary table. */
- unsigned assoc;
- /** The number of cycles for each hash lookup. */
- Cycles hashDelay;
- /** The number of cycles to read the data. */
- Cycles hitLatency;
- /** The replacement policy. */
- Repl *rp;
- /** The subblock size in bytes. */
- unsigned subblockSize;
- };
-
- /**
- * Construct and initialize this tag store.
- * @param params The IIC parameters.
- * @todo
- * Should make a way to have less tags in the primary than blks in the
- * cache. Also should be able to specify number of secondary blks.
- */
- IIC(Params ¶ms);
-
- /**
- * Destructor.
- */
- virtual ~IIC();
-
- /**
- * Register the statistics.
- * @param name The name to prepend to the statistic descriptions.
- */
- void regStats(const std::string &name);
-
- /**
- * Regenerate the block address from the tag.
- * @param tag The tag of the block.
- * @param set Not needed for the iic.
- * @return The block address.
- */
- Addr regenerateBlkAddr(Addr tag, int set) {
- return (((Addr)tag << tagShift));
- }
-
- /**
- * Return the block size.
- * @return The block size.
- */
- unsigned
- getBlockSize() const
- {
- return blkSize;
- }
-
- /**
- * Return the subblock size.
- * @return The subblock size.
- */
- unsigned
- getSubBlockSize() const
- {
- return subSize;
- }
-
- /**
- * Return the hit latency.
- * @return the hit latency.
- */
- int getHitLatency() const
- {
- return hitLatency;
- }
-
- /**
- * Generate the tag from the address.
- * @param addr The address to a get a tag for.
- * @return the tag.
- */
- Addr extractTag(Addr addr) const
- {
- return (addr >> tagShift);
- }
-
- /**
- * Return the set, always 0 for IIC.
- * @return 0.
- */
- int extractSet(Addr addr) const
- {
- return 0;
- }
-
- /**
- * Get the block offset of an address.
- * @param addr The address to get the offset of.
- * @return the block offset of the address.
- */
- 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);
- }
-
- /**
- * Swap the position of two tags.
- * @param index1 The first tag location.
- * @param index2 The second tag location.
- */
- void tagSwap(unsigned long index1, unsigned long index2);
-
- /**
- * Clear the reference bit of the tag and return its old value.
- * @param index The pointer of the tag to manipulate.
- * @return The previous state of the reference bit.
- */
- bool clearRef(unsigned long index)
- {
- bool tmp = tagStore[index].isReferenced();
- tagStore[index].status &= ~BlkReferenced;
- return tmp;
- }
-
- /**
- * Invalidate a block.
- * @param blk The block to invalidate.
- */
- void invalidate(BlkType *blk);
-
- /**
- * Access block and update replacement data. May not succeed, in which case
- * NULL pointer is returned. This has all the implications of a cache
- * access and should only be used as such.
- * Returns the access latency and inCache flags as a side effect.
- * @param addr The address to find.
- * @param asid The address space ID.
- * @param lat The access latency.
- * @return A pointer to the block found, if any.
- */
- IICTag* accessBlock(Addr addr, Cycles &lat, int context_src);
-
- /**
- * Find the block, do not update the replacement data.
- * @param addr The address to find.
- * @param asid The address space ID.
- * @return A pointer to the block found, if any.
- */
- IICTag* 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.
- */
- IICTag* findVictim(Addr addr, PacketList &writebacks);
-
- void insertBlock(Addr addr, BlkType *blk, int context_src);
- /**
- *iterated through all blocks and clear all locks
- *Needed to clear all lock tracking at once
- */
- virtual void clearLocks();
-
- /**
- * Called at end of simulation to complete average block reference stats.
- */
- virtual void cleanupRefs();
-
- /**
- * Visit each block in the tag store and apply a visitor to the
- * block.
- *
- * The visitor should be a function (or object that behaves like a
- * function) that takes a cache block reference as its parameter
- * and returns a bool. A visitor can request the traversal to be
- * stopped by returning false, returning true causes it to be
- * called for the next block in the tag store.
- *
- * \param visitor Visitor to call on each block.
- */
- template <typename V>
- void forEachBlk(V &visitor) {
- for (unsigned i = 0; i < numTags; ++i) {
- if (!visitor(tagStore[i]))
- return;
- }
- }
-
-private:
- /**
- * Return the hash of the address.
- * @param addr The address to hash.
- * @return the hash of the address.
- */
- unsigned hash(Addr addr) const;
-
- /**
- * Search for a block in the secondary tag store. Returns the number of
- * hash lookups as a side effect.
- * @param asid The address space ID.
- * @param tag The tag to match.
- * @param chain_ptr The first entry to search.
- * @param depth The number of hash lookups made while searching.
- * @return A pointer to the block if found.
- */
- IICTag *secondaryChain(Addr tag, unsigned long chain_ptr,
- int *depth) const;
-
- /**
- * Free the resources associated with the next replacement block.
- * @param writebacks A list of any writebacks to perform.
- */
- void freeReplacementBlock(PacketList & writebacks);
-
- /**
- * Return the pointer to a free data block.
- * @param writebacks A list of any writebacks to perform.
- * @return A pointer to a free data block.
- */
- unsigned long getFreeDataBlock(PacketList & writebacks);
-
- /**
- * Get a free tag in the given hash set.
- * @param set The hash set to search.
- * @param writebacks A list of any writebacks to perform.
- * @return a pointer to a free tag.
- */
- IICTag* getFreeTag(int set, PacketList & writebacks);
-
- /**
- * Free the resources associated with the given tag.
- * @param tag_ptr The tag to free.
- */
- void freeTag(IICTag *tag_ptr);
-
- /**
- * Mark the given data block as being available.
- * @param data_ptr The data block to free.
- */
- void freeDataBlock(unsigned long data_ptr);
-
-};
-#endif // __IIC_HH__
-
+++ /dev/null
-# Copyright (c) 2005-2008 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: Nathan Binkert
-
-from m5.SimObject import SimObject
-from m5.params import *
-class Repl(SimObject):
- type = 'Repl'
- abstract = True
- cxx_header = "mem/cache/tags/iic_repl/repl.hh"
-
-class GenRepl(Repl):
- type = 'GenRepl'
- cxx_header = "mem/cache/tags/iic_repl/gen.hh"
- fresh_res = Param.Int("Fresh pool residency time")
- num_pools = Param.Int("Number of priority pools")
- pool_res = Param.Int("Pool residency time")
+++ /dev/null
-/*
- * Copyright (c) 2002-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: Erik Hallnor
- * Steve Reinhardt
- */
-
-/**
- * @file
- * Definitions of the Generational replacement policy.
- */
-
-#include <string>
-
-#include "base/misc.hh"
-#include "base/types.hh"
-#include "mem/cache/tags/iic_repl/gen.hh"
-#include "mem/cache/tags/iic.hh"
-#include "params/GenRepl.hh"
-
-using namespace std;
-
-GenRepl::GenRepl(const Params *p) // fix this, should be set by cache
- : Repl(p), num_pools(p->num_pools), fresh_res(p->fresh_res),
- pool_res(p->pool_res), num_entries(0), num_pool_entries(0), misses(0),
- pools(new GenPool[num_pools+1])
-{
-}
-
-GenRepl::~GenRepl()
-{
- delete [] pools;
-}
-
-unsigned long
-GenRepl::getRepl()
-{
- unsigned long tmp;
- GenReplEntry *re;
- int i;
- int num_seen = 0;
- if (!(num_pool_entries>0)) {
- fatal("No blks available to replace");
- }
- num_entries--;
- num_pool_entries--;
- for (i = 0; i < num_pools; i++) {
- while ((re = pools[i].pop())) {
- num_seen++;
- // Remove invalidated entries
- if (!re->valid) {
- delete re;
- continue;
- }
- if (iic->clearRef(re->tag_ptr)) {
- pools[(((i+1)== num_pools)? i :i+1)].push(re, misses);
- }
- else {
- tmp = re->tag_ptr;
- delete re;
-
- repl_pool.sample(i);
-
- return tmp;
- }
- }
- }
- fatal("No replacement found");
- return 0xffffffff;
-}
-
-void
-GenRepl::doAdvance(std::list<unsigned long> &demoted)
-{
- int i;
- int num_seen = 0;
- GenReplEntry *re;
- misses++;
- for (i=0; i<num_pools; i++) {
- while (misses-pools[i].oldest > pool_res && (re = pools[i].pop())!=NULL) {
- if (iic->clearRef(re->tag_ptr)) {
- pools[(((i+1)== num_pools)? i :i+1)].push(re, misses);
- /** @todo Not really demoted, but use it for now. */
- demoted.push_back(re->tag_ptr);
- advance_pool.sample(i);
- }
- else {
- pools[(((i-1)<0)?i:i-1)].push(re, misses);
- demoted.push_back(re->tag_ptr);
- demote_pool.sample(i);
- }
- }
- num_seen += pools[i].size;
- }
- while (misses-pools[num_pools].oldest > fresh_res
- && (re = pools[num_pools].pop())!=NULL) {
- num_pool_entries++;
- if (iic->clearRef(re->tag_ptr)) {
- pools[num_pools/2].push(re, misses);
- /** @todo Not really demoted, but use it for now. */
- demoted.push_back(re->tag_ptr);
- advance_pool.sample(num_pools);
- }
- else {
- pools[num_pools/2-1].push(re, misses);
- demoted.push_back(re->tag_ptr);
- demote_pool.sample(num_pools);
- }
- }
-}
-
-void*
-GenRepl::add(unsigned long tag_index)
-{
- GenReplEntry *re = new GenReplEntry;
- re->tag_ptr = tag_index;
- re->valid = true;
- pools[num_pools].push(re, misses);
- num_entries++;
- return (void*)re;
-}
-
-void
-GenRepl::regStatsWithSuffix(const string name)
-{
- using namespace Stats;
-
- /** GEN statistics */
- repl_pool
- .init(0, 16, 1)
- .name(name + ".repl_pool_dist")
- .desc("Dist. of Repl. across pools")
- .flags(pdf)
- ;
-
- advance_pool
- .init(0, 16, 1)
- .name(name + ".advance_pool_dist")
- .desc("Dist. of Repl. across pools")
- .flags(pdf)
- ;
-
- demote_pool
- .init(0, 16, 1)
- .name(name + ".demote_pool_dist")
- .desc("Dist. of Repl. across pools")
- .flags(pdf)
- ;
-}
-
-int
-GenRepl::fixTag(void* _re, unsigned long old_index, unsigned long new_index)
-{
- GenReplEntry *re = (GenReplEntry*)_re;
- assert(re->valid);
- if (re->tag_ptr == old_index) {
- re->tag_ptr = new_index;
- return 1;
- }
- fatal("Repl entry: tag ptrs do not match");
- return 0;
-}
-
-bool
-GenRepl::findTagPtr(unsigned long index)
-{
- for (int i = 0; i < num_pools + 1; ++i) {
- list<GenReplEntry*>::const_iterator iter = pools[i].entries.begin();
- list<GenReplEntry*>::const_iterator end = pools[i].entries.end();
- for (; iter != end; ++iter) {
- if ((*iter)->valid && (*iter)->tag_ptr == index) {
- return true;
- }
- }
- }
- return false;
-}
-
-GenRepl *
-GenReplParams::create()
-{
- return new GenRepl(this);
-}
+++ /dev/null
-/*
- * Copyright (c) 2002-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: Erik Hallnor
- */
-
-/**
- * @file
- * Declarations of generational replacement policy
- */
-
-#ifndef ___GEN_HH__
-#define __GEN_HH__
-
-#include <list>
-
-#include "base/statistics.hh"
-#include "mem/cache/tags/iic_repl/repl.hh"
-#include "params/GenRepl.hh"
-
-/**
- * Generational Replacement entry.
- */
-class GenReplEntry
-{
- public:
- /** Valid flag, used to quickly invalidate bogus entries. */
- bool valid;
- /** The difference between this entry and the previous in the pool. */
- int delta;
- /** Pointer to the corresponding tag in the IIC. */
- unsigned long tag_ptr;
-};
-
-/**
- * Generational replacement pool
- */
-class GenPool
-{
- public:
- /** The time the last entry was added. */
- Tick newest;
- /** The time the oldest entry was added. */
- Tick oldest;
- /** List of the replacement entries in this pool. */
- std::list<GenReplEntry*> entries;
-
- /** The number of entries in this pool. */
- int size;
-
- /**
- * Simple constructor.
- */
- GenPool() {
- newest = 0;
- oldest = 0;
- size = 0;
- }
-
- /**
- * Add an entry to this pool.
- * @param re The entry to add.
- * @param now The current time.
- */
- void push(GenReplEntry *re, Tick now) {
- ++size;
- if (!entries.empty()) {
- re->delta = now - newest;
- newest = now;
- } else {
- re->delta = 0;
- newest = oldest = now;
- }
- entries.push_back(re);
- }
-
- /**
- * Remove an entry from the pool.
- * @return The entry at the front of the list.
- */
- GenReplEntry* pop() {
- GenReplEntry *tmp = NULL;
- if (!entries.empty()) {
- --size;
- tmp = entries.front();
- entries.pop_front();
- oldest += tmp->delta;
- }
- return tmp;
- }
-
- /**
- * Return the entry at the front of the list.
- * @return the entry at the front of the list.
- */
- GenReplEntry* top() {
- return entries.front();
- }
-
- /**
- * Destructor.
- */
- ~GenPool() {
- while (!entries.empty()) {
- GenReplEntry *tmp = entries.front();
- entries.pop_front();
- delete tmp;
- }
- }
-};
-
-/**
- * Generational replacement policy for use with the IIC.
- * @todo update to use STL and for efficiency
- */
-class GenRepl : public Repl
-{
- public:
- /** The number of pools. */
- int num_pools;
- /** The amount of time to stay in the fresh pool. */
- int fresh_res;
- /** The amount of time to stay in the normal pools. */
- int pool_res;
- /** The maximum number of entries */
- int num_entries;
- /** The number of entries currently in the pools. */
- int num_pool_entries;
- /** The number of misses. Used as the internal time. */
- Tick misses;
- /** The array of pools. */
- GenPool *pools;
-
- // Statistics
-
- /**
- * @addtogroup CacheStatistics
- * @{
- */
- /** The number of replacements from each pool. */
- Stats::Distribution repl_pool;
- /** The number of advances out of each pool. */
- Stats::Distribution advance_pool;
- /** The number of demotions from each pool. */
- Stats::Distribution demote_pool;
- /**
- * @}
- */
-
- typedef GenReplParams Params;
- GenRepl(const Params *p);
-
- /**
- * Destructor.
- */
- ~GenRepl();
-
- /**
- * Returns the tag pointer of the cache block to replace.
- * @return The tag to replace.
- */
- virtual unsigned long getRepl();
-
- /**
- * Update replacement data
- */
- virtual void doAdvance(std::list<unsigned long> &demoted);
-
- /**
- * Add a tag to the replacement policy and return a pointer to the
- * replacement entry.
- * @param tag_index The tag to add.
- * @return The replacement entry.
- */
- virtual void* add(unsigned long tag_index);
-
- /**
- * Register statistics.
- * @param name The name to prepend to statistic descriptions.
- */
- virtual void regStatsWithSuffix(const std::string name);
-
- /**
- * Update the tag pointer to when the tag moves.
- * @param re The replacement entry of the tag.
- * @param old_index The old tag pointer.
- * @param new_index The new tag pointer.
- * @return 1 if successful, 0 otherwise.
- */
- virtual int fixTag(void *re, unsigned long old_index,
- unsigned long new_index);
-
- /**
- * Remove this entry from the replacement policy.
- * @param re The replacement entry to remove
- */
- virtual void removeEntry(void *re)
- {
- ((GenReplEntry*)re)->valid = false;
- }
-
- protected:
- /**
- * Debug function to verify that there is only one repl entry per tag.
- * @param index The tag index to check.
- */
- bool findTagPtr(unsigned long index);
-};
-
-#endif /* __GEN_HH__ */
+++ /dev/null
-/*
- * Copyright (c) 2002-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: Erik Hallnor
- * Steve Reinhardt
- * Nathan Binkert
- */
-
-/**
- * @file
- * Declaration of a base replacement policy class.
- */
-
-#ifndef __REPL_HH__
-#define __REPL_HH__
-
-#include <list>
-#include <string>
-
-#include "base/types.hh"
-#include "cpu/smt.hh"
-#include "sim/sim_object.hh"
-
-class IIC;
-
-/**
- * A pure virtual base class that defines the interface of a replacement
- * policy.
- */
-class Repl : public SimObject
-{
- public:
- /** Pointer to the IIC using this policy. */
- IIC *iic;
-
- Repl (const Params *params)
- : SimObject(params)
- {
- iic = NULL;
- }
-
- /**
- * Set the back pointer to the IIC.
- * @param iic_ptr Pointer to the IIC.
- */
- void setIIC(IIC *iic_ptr)
- {
- iic = iic_ptr;
- }
-
- /**
- * Returns the tag pointer of the cache block to replace.
- * @return The tag to replace.
- */
- virtual unsigned long getRepl() = 0;
-
- /**
- * Update replacement data
- */
- virtual void doAdvance(std::list<unsigned long> &demoted) = 0;
-
- /**
- * Add a tag to the replacement policy and return a pointer to the
- * replacement entry.
- * @param tag_index The tag to add.
- * @return The replacement entry.
- */
- virtual void* add(unsigned long tag_index) = 0;
-
- /**
- * Register statistics.
- * @param name The name to prepend to statistic descriptions.
- */
- virtual void regStatsWithSuffix(const std::string name) = 0;
-
- /**
- * Update the tag pointer to when the tag moves.
- * @param re The replacement entry of the tag.
- * @param old_index The old tag pointer.
- * @param new_index The new tag pointer.
- * @return 1 if successful, 0 otherwise.
- */
- virtual int fixTag(void *re, unsigned long old_index,
- unsigned long new_index) = 0;
-
- /**
- * Remove this entry from the replacement policy.
- * @param re The replacement entry to remove
- */
- virtual void removeEntry(void *re) = 0;
-};
-
-#endif /* SMT_REPL_HH */
*/
#define USE_CACHE_LRU 1
#define USE_CACHE_FALRU 1
-#define USE_CACHE_IIC 1
+