summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mem/cache/tags/SConscript1
-rw-r--r--src/mem/cache/tags/Tags.py18
-rw-r--r--src/mem/cache/tags/base.cc23
-rw-r--r--src/mem/cache/tags/base.hh26
-rw-r--r--src/mem/cache/tags/base_set_assoc.cc62
-rw-r--r--src/mem/cache/tags/base_set_assoc.hh86
-rw-r--r--src/mem/cache/tags/indexing_policies/IndexingPolicies.py55
-rw-r--r--src/mem/cache/tags/indexing_policies/SConscript36
-rw-r--r--src/mem/cache/tags/indexing_policies/base.cc102
-rw-r--r--src/mem/cache/tags/indexing_policies/base.hh163
-rw-r--r--src/mem/cache/tags/indexing_policies/set_associative.cc82
-rw-r--r--src/mem/cache/tags/indexing_policies/set_associative.hh132
-rw-r--r--src/mem/cache/tags/indexing_policies/skewed_associative.cc (renamed from src/mem/cache/tags/skewed_assoc.cc)75
-rw-r--r--src/mem/cache/tags/indexing_policies/skewed_associative.hh (renamed from src/mem/cache/tags/skewed_assoc.hh)97
-rw-r--r--src/mem/cache/tags/sector_tags.cc140
-rw-r--r--src/mem/cache/tags/sector_tags.hh59
16 files changed, 768 insertions, 389 deletions
diff --git a/src/mem/cache/tags/SConscript b/src/mem/cache/tags/SConscript
index 1a3780ff1..136abac2c 100644
--- a/src/mem/cache/tags/SConscript
+++ b/src/mem/cache/tags/SConscript
@@ -36,4 +36,3 @@ Source('base.cc')
Source('base_set_assoc.cc')
Source('fa_lru.cc')
Source('sector_tags.cc')
-Source('skewed_assoc.cc')
diff --git a/src/mem/cache/tags/Tags.py b/src/mem/cache/tags/Tags.py
index 781ac8e3f..8e302898c 100644
--- a/src/mem/cache/tags/Tags.py
+++ b/src/mem/cache/tags/Tags.py
@@ -38,6 +38,7 @@
from m5.params import *
from m5.proxy import *
from ClockedObject import ClockedObject
+from IndexingPolicies import *
class BaseTags(ClockedObject):
type = 'BaseTags'
@@ -64,6 +65,14 @@ class BaseTags(ClockedObject):
sequential_access = Param.Bool(Parent.sequential_access,
"Whether to access tags and data sequentially")
+ # Get indexing policy
+ indexing_policy = Param.BaseIndexingPolicy(SetAssociative(),
+ "Indexing policy")
+
+ # Set the indexing entry size as the block size
+ entry_size = Param.Int(Parent.cache_line_size,
+ "Indexing entry size in bytes")
+
class BaseSetAssoc(BaseTags):
type = 'BaseSetAssoc'
cxx_header = "mem/cache/tags/base_set_assoc.hh"
@@ -85,6 +94,9 @@ class SectorTags(BaseTags):
# Number of sub-sectors (data blocks) per sector
num_blocks_per_sector = Param.Int(1, "Number of sub-sectors per sector");
+ # The indexing entry now is a sector block
+ entry_size = Parent.cache_line_size * Self.num_blocks_per_sector
+
# Get replacement policy from the parent (cache)
replacement_policy = Param.BaseReplacementPolicy(
Parent.replacement_policy, "Replacement policy")
@@ -96,6 +108,6 @@ class FALRU(BaseTags):
min_tracked_cache_size = Param.MemorySize("128kB", "Minimum cache size for"
" which we track statistics")
-class SkewedAssoc(BaseSetAssoc):
- type = 'SkewedAssoc'
- cxx_header = "mem/cache/tags/skewed_assoc.hh"
+
+ # This tag uses its own embedded indexing
+ indexing_policy = NULL
diff --git a/src/mem/cache/tags/base.cc b/src/mem/cache/tags/base.cc
index 303eb04e2..dddb8c71d 100644
--- a/src/mem/cache/tags/base.cc
+++ b/src/mem/cache/tags/base.cc
@@ -52,6 +52,7 @@
#include "base/types.hh"
#include "mem/cache/base.hh"
+#include "mem/cache/tags/indexing_policies/base.hh"
#include "mem/request.hh"
#include "sim/core.hh"
#include "sim/sim_exit.hh"
@@ -64,7 +65,7 @@ BaseTags::BaseTags(const Params *p)
accessLatency(p->sequential_access ?
p->tag_latency + p->data_latency :
std::max(p->tag_latency, p->data_latency)),
- cache(nullptr),
+ cache(nullptr), indexingPolicy(p->indexing_policy),
warmupBound((p->warmup_percentage/100.0) * (p->size / p->block_size)),
warmedUp(false), numBlocks(p->size / p->block_size),
dataBlks(new uint8_t[p->size]) // Allocate data storage in one big chunk
@@ -78,10 +79,10 @@ BaseTags::setCache(BaseCache *_cache)
cache = _cache;
}
-std::vector<ReplaceableEntry*>
-BaseTags::getPossibleLocations(const Addr addr) const
+ReplaceableEntry*
+BaseTags::findBlockBySetAndWay(int set, int way) const
{
- panic("Unimplemented getPossibleLocations for tags subclass");
+ return indexingPolicy->getEntry(set, way);
}
CacheBlk*
@@ -90,12 +91,12 @@ BaseTags::findBlock(Addr addr, bool is_secure) const
// Extract block tag
Addr tag = extractTag(addr);
- // Find possible locations for the given address
- const std::vector<ReplaceableEntry*> locations =
- getPossibleLocations(addr);
+ // Find possible entries that may contain the given address
+ const std::vector<ReplaceableEntry*> entries =
+ indexingPolicy->getPossibleEntries(addr);
// Search for block
- for (const auto& location : locations) {
+ for (const auto& location : entries) {
CacheBlk* blk = static_cast<CacheBlk*>(location);
if ((blk->tag == tag) && blk->isValid() &&
(blk->isSecure() == is_secure)) {
@@ -134,6 +135,12 @@ BaseTags::insertBlock(const Addr addr, const bool is_secure,
dataAccesses += 1;
}
+Addr
+BaseTags::extractTag(const Addr addr) const
+{
+ return indexingPolicy->extractTag(addr);
+}
+
void
BaseTags::cleanupRefsVisitor(CacheBlk &blk)
{
diff --git a/src/mem/cache/tags/base.hh b/src/mem/cache/tags/base.hh
index 7badc46c2..589de37c0 100644
--- a/src/mem/cache/tags/base.hh
+++ b/src/mem/cache/tags/base.hh
@@ -62,6 +62,7 @@
#include "sim/clocked_object.hh"
class BaseCache;
+class IndexingPolicy;
class ReplaceableEntry;
/**
@@ -87,6 +88,9 @@ class BaseTags : public ClockedObject
/** Pointer to the parent cache. */
BaseCache *cache;
+ /** Indexing policy */
+ BaseIndexingPolicy *indexingPolicy;
+
/**
* The number of tags that need to be touched to meet the warmup
* percentage.
@@ -161,18 +165,6 @@ class BaseTags : public ClockedObject
*/
void setCache(BaseCache *_cache);
- /**
- * Find all possible block locations for insertion and replacement of
- * an address. Should be called immediately before ReplacementPolicy's
- * findVictim() not to break cache resizing.
- * Returns blocks in all ways belonging to the set of the address.
- *
- * @param addr The addr to a find possible locations for.
- * @return The possible locations.
- */
- virtual std::vector<ReplaceableEntry*> getPossibleLocations(
- const Addr addr) const;
-
public:
typedef BaseTagsParams Params;
BaseTags(const Params *p);
@@ -226,7 +218,7 @@ class BaseTags : public ClockedObject
* @param way The way of the block.
* @return The block.
*/
- virtual ReplaceableEntry* findBlockBySetAndWay(int set, int way) const = 0;
+ virtual ReplaceableEntry* findBlockBySetAndWay(int set, int way) const;
/**
* Align an address to the block size.
@@ -303,7 +295,13 @@ class BaseTags : public ClockedObject
virtual CacheBlk* accessBlock(Addr addr, bool is_secure, Cycles &lat) = 0;
- virtual Addr extractTag(Addr addr) const = 0;
+ /**
+ * Generate the tag from the given address.
+ *
+ * @param addr The address to get the tag from.
+ * @return The tag of the address.
+ */
+ virtual Addr extractTag(const Addr addr) const;
/**
* Insert the new block into the cache and update stats.
diff --git a/src/mem/cache/tags/base_set_assoc.cc b/src/mem/cache/tags/base_set_assoc.cc
index 543231cd9..1a04c08a9 100644
--- a/src/mem/cache/tags/base_set_assoc.cc
+++ b/src/mem/cache/tags/base_set_assoc.cc
@@ -42,7 +42,7 @@
/**
* @file
- * Definitions of a base set associative tag store.
+ * Definitions of a conventional tag store.
*/
#include "mem/cache/tags/base_set_assoc.hh"
@@ -52,27 +52,14 @@
#include "base/intmath.hh"
BaseSetAssoc::BaseSetAssoc(const Params *p)
- :BaseTags(p), assoc(p->assoc), allocAssoc(p->assoc),
- blks(p->size / p->block_size),
- numSets(p->size / (p->block_size * p->assoc)),
+ :BaseTags(p), allocAssoc(p->assoc), blks(p->size / p->block_size),
sequentialAccess(p->sequential_access),
- sets(p->size / (p->block_size * p->assoc)),
replacementPolicy(p->replacement_policy)
{
// Check parameters
if (blkSize < 4 || !isPowerOf2(blkSize)) {
fatal("Block size must be at least 4 and a power of 2");
}
- if (!isPowerOf2(numSets)) {
- fatal("# of sets must be non-zero and a power of 2");
- }
- if (assoc <= 0) {
- fatal("associativity must be greater than zero");
- }
-
- setShift = floorLog2(blkSize);
- setMask = numSets - 1;
- tagShift = setShift + floorLog2(numSets);
}
void
@@ -81,35 +68,19 @@ BaseSetAssoc::init(BaseCache* cache)
// Set parent cache
setCache(cache);
- // Initialize blocks
- unsigned blkIndex = 0; // index into blks array
- for (unsigned i = 0; i < numSets; ++i) {
- sets[i].resize(assoc);
-
- // link in the data blocks
- for (unsigned j = 0; j < assoc; ++j) {
- // Select block within the set to be linked
- BlkType*& blk = sets[i][j];
-
- // Locate next cache block
- blk = &blks[blkIndex];
-
- // Associate a data chunk to the block
- blk->data = &dataBlks[blkSize*blkIndex];
+ // Initialize all blocks
+ for (unsigned blk_index = 0; blk_index < numBlocks; blk_index++) {
+ // Locate next cache block
+ BlkType* blk = &blks[blk_index];
- // Associate a replacement data entry to the block
- blk->replacementData = replacementPolicy->instantiateEntry();
+ // Link block to indexing policy
+ indexingPolicy->setEntry(blk, blk_index);
- // 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;
+ // Associate a data chunk to the block
+ blk->data = &dataBlks[blkSize*blk_index];
- // Set its index
- blk->setPosition(i, j);
-
- // Update block index
- ++blkIndex;
- }
+ // Associate a replacement data entry to the block
+ blk->replacementData = replacementPolicy->instantiateEntry();
}
}
@@ -125,14 +96,11 @@ BaseSetAssoc::invalidate(CacheBlk *blk)
replacementPolicy->invalidate(blk->replacementData);
}
-ReplaceableEntry*
-BaseSetAssoc::findBlockBySetAndWay(int set, int way) const
-{
- return sets[set][way];
-}
-
BaseSetAssoc *
BaseSetAssocParams::create()
{
+ // There must be a indexing policy
+ fatal_if(!indexing_policy, "An indexing policy is required");
+
return new BaseSetAssoc(this);
}
diff --git a/src/mem/cache/tags/base_set_assoc.hh b/src/mem/cache/tags/base_set_assoc.hh
index 2f4f7309d..e06417224 100644
--- a/src/mem/cache/tags/base_set_assoc.hh
+++ b/src/mem/cache/tags/base_set_assoc.hh
@@ -59,71 +59,35 @@
#include "mem/cache/blk.hh"
#include "mem/cache/replacement_policies/base.hh"
#include "mem/cache/tags/base.hh"
+#include "mem/cache/tags/indexing_policies/base.hh"
#include "params/BaseSetAssoc.hh"
/**
- * A BaseSetAssoc cache tag store.
+ * A basic cache tag store.
* @sa \ref gem5MemorySystem "gem5 Memory System"
*
* The BaseSetAssoc placement policy divides the cache into s sets of w
- * cache lines (ways). A cache line is mapped onto a set, and can be placed
- * into any of the ways of this set.
+ * cache lines (ways).
*/
class BaseSetAssoc : public BaseTags
{
public:
/** Typedef the block type used in this tag store. */
typedef CacheBlk BlkType;
- /** Typedef the set type used in this tag store. */
- typedef std::vector<CacheBlk*> SetType;
protected:
- /** The associativity of the cache. */
- const unsigned assoc;
/** The allocatable associativity of the cache (alloc mask). */
unsigned allocAssoc;
/** The cache blocks. */
std::vector<BlkType> blks;
- /** The number of sets in the cache. */
- const unsigned numSets;
-
/** Whether tags and data are accessed sequentially. */
const bool sequentialAccess;
- /** The cache sets. */
- std::vector<SetType> sets;
-
- /** 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;
-
/** Replacement policy */
BaseReplacementPolicy *replacementPolicy;
- /**
- * Find all possible block locations for insertion and replacement of
- * an address. Should be called immediately before ReplacementPolicy's
- * findVictim() not to break cache resizing.
- * Returns blocks in all ways belonging to the set of the address.
- *
- * @param addr The addr to a find possible locations for.
- * @return The possible locations.
- */
- std::vector<ReplaceableEntry*> getPossibleLocations(const Addr addr) const
- override
- {
- std::vector<ReplaceableEntry*> locations;
- for (const auto& blk : sets[extractSet(addr)]) {
- locations.push_back(static_cast<ReplaceableEntry*>(blk));
- }
- return locations;
- }
-
public:
/** Convenience typedef. */
typedef BaseSetAssocParams Params;
@@ -205,15 +169,6 @@ class BaseSetAssoc : public BaseTags
}
/**
- * Find a block given set and way.
- *
- * @param set The set of the block.
- * @param way The way of the block.
- * @return The block.
- */
- ReplaceableEntry* findBlockBySetAndWay(int set, int way) const override;
-
- /**
* Find replacement victim based on address. The list of evicted blocks
* only contains the victim.
*
@@ -225,13 +180,13 @@ class BaseSetAssoc : public BaseTags
CacheBlk* findVictim(Addr addr, const bool is_secure,
std::vector<CacheBlk*>& evict_blks) const override
{
- // Get possible locations for the victim block
- std::vector<ReplaceableEntry*> locations = getPossibleLocations(addr);
+ // Get possible entries to be victimized
+ const std::vector<ReplaceableEntry*> entries =
+ indexingPolicy->getPossibleEntries(addr);
// Choose replacement victim from replacement candidates
CacheBlk* victim = static_cast<CacheBlk*>(replacementPolicy->getVictim(
- std::vector<ReplaceableEntry*>(
- locations.begin(), locations.end())));
+ entries));
// There is only one eviction for this replacement
evict_blks.push_back(victim);
@@ -285,25 +240,14 @@ class BaseSetAssoc : public BaseTags
}
/**
- * 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 override
- {
- return (addr >> tagShift);
- }
-
- /**
- * Regenerate the block address from the tag and set.
+ * Regenerate the block address from the tag and indexing location.
*
* @param block The block.
* @return the block address.
*/
Addr regenerateBlkAddr(const CacheBlk* blk) const override
{
- const Addr set = blk->getSet() << setShift;
- return ((blk->tag << tagShift) | set);
+ return indexingPolicy->regenerateAddr(blk->tag, blk);
}
void forEachBlk(std::function<void(CacheBlk &)> visitor) override {
@@ -320,18 +264,6 @@ class BaseSetAssoc : public BaseTags
}
return false;
}
-
- private:
- /**
- * 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);
- }
};
#endif //__MEM_CACHE_TAGS_BASE_SET_ASSOC_HH__
diff --git a/src/mem/cache/tags/indexing_policies/IndexingPolicies.py b/src/mem/cache/tags/indexing_policies/IndexingPolicies.py
new file mode 100644
index 000000000..c33a1d7df
--- /dev/null
+++ b/src/mem/cache/tags/indexing_policies/IndexingPolicies.py
@@ -0,0 +1,55 @@
+# Copyright (c) 2018 Inria
+# 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: Daniel Carvalho
+
+from m5.params import *
+from m5.proxy import *
+from m5.SimObject import SimObject
+
+class BaseIndexingPolicy(SimObject):
+ type = 'BaseIndexingPolicy'
+ abstract = True
+ cxx_header = "mem/cache/tags/indexing_policies/base.hh"
+
+ # Get the size from the parent (cache)
+ size = Param.MemorySize(Parent.size, "capacity in bytes")
+
+ # Get the entry size from the parent (tags)
+ entry_size = Param.Int(Parent.entry_size, "entry size in bytes")
+
+ # Get the associativity
+ assoc = Param.Int(Parent.assoc, "associativity")
+
+class SetAssociative(BaseIndexingPolicy):
+ type = 'SetAssociative'
+ cxx_class = 'SetAssociative'
+ cxx_header = "mem/cache/tags/indexing_policies/set_associative.hh"
+
+class SkewedAssociative(BaseIndexingPolicy):
+ type = 'SkewedAssociative'
+ cxx_class = 'SkewedAssociative'
+ cxx_header = "mem/cache/tags/indexing_policies/skewed_associative.hh"
diff --git a/src/mem/cache/tags/indexing_policies/SConscript b/src/mem/cache/tags/indexing_policies/SConscript
new file mode 100644
index 000000000..9f57bd641
--- /dev/null
+++ b/src/mem/cache/tags/indexing_policies/SConscript
@@ -0,0 +1,36 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2018 Inria.
+#
+# 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: Daniel Carvalho
+
+Import('*')
+
+SimObject('IndexingPolicies.py')
+
+Source('base.cc')
+Source('set_associative.cc')
+Source('skewed_associative.cc')
diff --git a/src/mem/cache/tags/indexing_policies/base.cc b/src/mem/cache/tags/indexing_policies/base.cc
new file mode 100644
index 000000000..f27bedd4a
--- /dev/null
+++ b/src/mem/cache/tags/indexing_policies/base.cc
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2018 Inria
+ * Copyright (c) 2012-2014,2017 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) 2003-2005,2014 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: Daniel Carvalho
+ * Erik Hallnor
+ */
+
+/**
+ * @file
+ * Definitions of a common framework for indexing policies.
+ */
+
+#include "mem/cache/tags/indexing_policies/base.hh"
+
+#include <cstdlib>
+
+#include "base/intmath.hh"
+#include "base/logging.hh"
+#include "mem/cache/replacement_policies/base.hh"
+
+BaseIndexingPolicy::BaseIndexingPolicy(const Params *p)
+ : SimObject(p), assoc(p->assoc),
+ numSets(p->size / (p->entry_size * assoc)),
+ setShift(floorLog2(p->entry_size)), setMask(numSets - 1), sets(numSets),
+ tagShift(setShift + floorLog2(numSets))
+{
+ fatal_if(!isPowerOf2(numSets), "# of sets must be non-zero and a power " \
+ "of 2");
+ fatal_if(assoc <= 0, "associativity must be greater than zero");
+
+ // Make space for the entries
+ for (uint32_t i = 0; i < numSets; ++i) {
+ sets[i].resize(assoc);
+ }
+}
+
+ReplaceableEntry*
+BaseIndexingPolicy::getEntry(const uint32_t set, const uint32_t way) const
+{
+ return sets[set][way];
+}
+
+void
+BaseIndexingPolicy::setEntry(ReplaceableEntry* entry, const uint64_t index)
+{
+ // Calculate set and way from entry index
+ const std::lldiv_t div_result = std::div((long long)index, assoc);
+ const uint32_t set = div_result.quot;
+ const uint32_t way = div_result.rem;
+
+ // Sanity check
+ assert(set < numSets);
+
+ // Assign a free pointer
+ sets[set][way] = entry;
+
+ // Inform the entry its position
+ entry->setPosition(set, way);
+}
+
+Addr
+BaseIndexingPolicy::extractTag(const Addr addr) const
+{
+ return (addr >> tagShift);
+}
diff --git a/src/mem/cache/tags/indexing_policies/base.hh b/src/mem/cache/tags/indexing_policies/base.hh
new file mode 100644
index 000000000..02c175d1a
--- /dev/null
+++ b/src/mem/cache/tags/indexing_policies/base.hh
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2018 Inria
+ * Copyright (c) 2012-2014,2017 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) 2003-2005,2014 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: Daniel Carvalho
+ * Erik Hallnor
+ */
+
+/**
+ * @file
+ * Declaration of a common framework for indexing policies.
+ */
+
+#ifndef __MEM_CACHE_INDEXING_POLICIES_BASE_HH__
+#define __MEM_CACHE_INDEXING_POLICIES_BASE_HH__
+
+#include <vector>
+
+#include "params/BaseIndexingPolicy.hh"
+#include "sim/sim_object.hh"
+
+class ReplaceableEntry;
+
+/**
+ * A common base class for indexing table locations. Classes that inherit
+ * from it determine hash functions that should be applied based on the set
+ * and way. These functions are then applied to re-map the original values.
+ * @sa \ref gem5MemorySystem "gem5 Memory System"
+ */
+class BaseIndexingPolicy : public SimObject
+{
+ protected:
+ /**
+ * The associativity.
+ */
+ const unsigned assoc;
+
+ /**
+ * The number of sets in the cache.
+ */
+ const uint32_t numSets;
+
+ /**
+ * The amount to shift the address to get the set.
+ */
+ const int setShift;
+
+ /**
+ * Mask out all bits that aren't part of the set index.
+ */
+ const unsigned setMask;
+
+ /**
+ * The cache sets.
+ */
+ std::vector<std::vector<ReplaceableEntry*>> sets;
+
+ /**
+ * The amount to shift the address to get the tag.
+ */
+ const int tagShift;
+
+ public:
+ /**
+ * Convenience typedef.
+ */
+ typedef BaseIndexingPolicyParams Params;
+
+ /**
+ * Construct and initialize this policy.
+ */
+ BaseIndexingPolicy(const Params *p);
+
+ /**
+ * Destructor.
+ */
+ ~BaseIndexingPolicy() {};
+
+ /**
+ * Associate a pointer to an entry to its physical counterpart.
+ *
+ * @param entry The entry pointer.
+ * @param index An unique index for the entry.
+ */
+ void setEntry(ReplaceableEntry* entry, const uint64_t index);
+
+ /**
+ * Get an entry based on its set and way. All entries must have been set
+ * already before calling this function.
+ *
+ * @param set The set of the desired entry.
+ * @param way The way of the desired entry.
+ * @return entry The entry pointer.
+ */
+ ReplaceableEntry* getEntry(const uint32_t set, const uint32_t way) const;
+
+ /**
+ * Generate the tag from the given address.
+ *
+ * @param addr The address to get the tag from.
+ * @return The tag of the address.
+ */
+ Addr extractTag(const Addr addr) const;
+
+ /**
+ * Find all possible entries for insertion and replacement of an address.
+ * Should be called immediately before ReplacementPolicy's findVictim()
+ * not to break cache resizing.
+ *
+ * @param addr The addr to a find possible entries for.
+ * @return The possible entries.
+ */
+ virtual std::vector<ReplaceableEntry*> getPossibleEntries(const Addr addr)
+ const = 0;
+
+ /**
+ * Regenerate an entry's address from its tag and assigned indexing bits.
+ *
+ * @param tag The tag bits.
+ * @param entry The entry.
+ * @return the entry's original address.
+ */
+ virtual Addr regenerateAddr(const Addr tag, const ReplaceableEntry* entry)
+ const = 0;
+};
+
+#endif //__MEM_CACHE_INDEXING_POLICIES_BASE_HH__
diff --git a/src/mem/cache/tags/indexing_policies/set_associative.cc b/src/mem/cache/tags/indexing_policies/set_associative.cc
new file mode 100644
index 000000000..d5fe8ffd0
--- /dev/null
+++ b/src/mem/cache/tags/indexing_policies/set_associative.cc
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2018 Inria
+ * Copyright (c) 2012-2014,2017 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) 2003-2005,2014 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: Daniel Carvalho
+ * Erik Hallnor
+ */
+
+/**
+ * @file
+ * Definitions of a set associative indexing policy.
+ */
+
+#include "mem/cache/tags/indexing_policies/set_associative.hh"
+
+#include "mem/cache/replacement_policies/base.hh"
+
+SetAssociative::SetAssociative(const Params *p)
+ : BaseIndexingPolicy(p)
+{
+}
+
+uint32_t
+SetAssociative::extractSet(const Addr addr) const
+{
+ return (addr >> setShift) & setMask;
+}
+
+Addr
+SetAssociative::regenerateAddr(const Addr tag, const ReplaceableEntry* entry)
+ const
+{
+ return (tag << tagShift) | (entry->getSet() << setShift);
+}
+
+std::vector<ReplaceableEntry*>
+SetAssociative::getPossibleEntries(const Addr addr) const
+{
+ return sets[extractSet(addr)];
+}
+
+SetAssociative*
+SetAssociativeParams::create()
+{
+ return new SetAssociative(this);
+}
diff --git a/src/mem/cache/tags/indexing_policies/set_associative.hh b/src/mem/cache/tags/indexing_policies/set_associative.hh
new file mode 100644
index 000000000..216172395
--- /dev/null
+++ b/src/mem/cache/tags/indexing_policies/set_associative.hh
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2018 Inria
+ * Copyright (c) 2012-2014,2017 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) 2003-2005,2014 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: Daniel Carvalho
+ * Erik Hallnor
+ */
+
+/**
+ * @file
+ * Declaration of a set associative indexing policy.
+ */
+
+#ifndef __MEM_CACHE_INDEXING_POLICIES_SET_ASSOCIATIVE_HH__
+#define __MEM_CACHE_INDEXING_POLICIES_SET_ASSOCIATIVE_HH__
+
+#include <vector>
+
+#include "mem/cache/tags/indexing_policies/base.hh"
+#include "params/SetAssociative.hh"
+
+class ReplaceableEntry;
+
+/**
+ * A set associative indexing policy.
+ * @sa \ref gem5MemorySystem "gem5 Memory System"
+ *
+ * The set associative indexing policy has an immutable/identity mapping, so a
+ * value x is always mapped to set x, independent of the way, that is,
+ * Hash(A, 0) = Hash(A, 1) = Hash(A, N-1), where N is the number of ways.
+ *
+ * For example, let's assume address A maps to set 3 on way 0. This policy
+ * makes so that A is also mappable to set 3 on every other way. Visually, the
+ * possible locations of A are, for a table with 4 ways and 8 sets:
+ * Way 0 1 2 3
+ * Set _ _ _ _
+ * 0 |_| |_| |_| |_|
+ * 1 |_| |_| |_| |_|
+ * 2 |_| |_| |_| |_|
+ * 3 |X| |X| |X| |X|
+ * 4 |_| |_| |_| |_|
+ * 5 |_| |_| |_| |_|
+ * 6 |_| |_| |_| |_|
+ * 7 |_| |_| |_| |_|
+ */
+class SetAssociative : public BaseIndexingPolicy
+{
+ private:
+ /**
+ * Apply a hash function to calculate address set.
+ *
+ * @param addr The address to calculate the set for.
+ * @return The set index for given combination of address and way.
+ */
+ uint32_t extractSet(const Addr addr) const;
+
+ public:
+ /**
+ * Convenience typedef.
+ */
+ typedef SetAssociativeParams Params;
+
+ /**
+ * Construct and initialize this policy.
+ */
+ SetAssociative(const Params *p);
+
+ /**
+ * Destructor.
+ */
+ ~SetAssociative() {};
+
+ /**
+ * Find all possible entries for insertion and replacement of an address.
+ * Should be called immediately before ReplacementPolicy's findVictim()
+ * not to break cache resizing.
+ * Returns entries in all ways belonging to the set of the address.
+ *
+ * @param addr The addr to a find possible entries for.
+ * @return The possible entries.
+ */
+ std::vector<ReplaceableEntry*> getPossibleEntries(const Addr addr) const
+ override;
+
+ /**
+ * Regenerate an entry's address from its tag and assigned set and way.
+ *
+ * @param tag The tag bits.
+ * @param entry The entry.
+ * @return the entry's original addr value.
+ */
+ Addr regenerateAddr(const Addr tag, const ReplaceableEntry* entry) const
+ override;
+};
+
+#endif //__MEM_CACHE_INDEXING_POLICIES_SET_ASSOCIATIVE_HH__
diff --git a/src/mem/cache/tags/skewed_assoc.cc b/src/mem/cache/tags/indexing_policies/skewed_associative.cc
index d92ab469a..d1765e5d6 100644
--- a/src/mem/cache/tags/skewed_assoc.cc
+++ b/src/mem/cache/tags/indexing_policies/skewed_associative.cc
@@ -30,18 +30,18 @@
/**
* @file
- * Definitions of a skewed associative placement policy.
+ * Definitions of a skewed associative indexing policy.
*/
-#include "mem/cache/tags/skewed_assoc.hh"
-
-#include <vector>
+#include "mem/cache/tags/indexing_policies/skewed_associative.hh"
#include "base/bitfield.hh"
+#include "base/intmath.hh"
#include "base/logging.hh"
+#include "mem/cache/replacement_policies/base.hh"
-SkewedAssoc::SkewedAssoc(const Params *p)
- : BaseSetAssoc(p), msbShift(floorLog2(numSets) - 1)
+SkewedAssociative::SkewedAssociative(const Params *p)
+ : BaseIndexingPolicy(p), msbShift(floorLog2(numSets) - 1)
{
if (assoc > NUM_SKEWING_FUNCTIONS) {
warn_once("Associativity higher than number of skewing functions. " \
@@ -59,7 +59,7 @@ SkewedAssoc::SkewedAssoc(const Params *p)
}
Addr
-SkewedAssoc::hash(const Addr addr) const
+SkewedAssociative::hash(const Addr addr) const
{
// Get relevant bits
const uint8_t lsb = bits<Addr>(addr, 0);
@@ -71,7 +71,7 @@ SkewedAssoc::hash(const Addr addr) const
}
Addr
-SkewedAssoc::dehash(const Addr addr) const
+SkewedAssociative::dehash(const Addr addr) const
{
// Get relevant bits. The original MSB is one bit away on the current MSB
// (which is the XOR bit). The original LSB can be retrieved from inverting
@@ -86,7 +86,7 @@ SkewedAssoc::dehash(const Addr addr) const
}
Addr
-SkewedAssoc::skew(const Addr addr, const unsigned way) const
+SkewedAssociative::skew(const Addr addr, const uint32_t way) const
{
// Assume an address of size A bits can be decomposed into
// {addr3, addr2, addr1, addr0}, where:
@@ -130,7 +130,7 @@ SkewedAssoc::skew(const Addr addr, const unsigned way) const
// If we have more than 8 ways, just pile them up on hashes. This is not
// the optimal solution, and can be improved by adding more skewing
// functions to the previous selector
- for (int i = 0; i < way/NUM_SKEWING_FUNCTIONS; i++) {
+ for (uint32_t i = 0; i < way/NUM_SKEWING_FUNCTIONS; i++) {
addr1 = hash(addr1);
}
@@ -138,7 +138,7 @@ SkewedAssoc::skew(const Addr addr, const unsigned way) const
}
Addr
-SkewedAssoc::deskew(const Addr addr, const unsigned way) const
+SkewedAssociative::deskew(const Addr addr, const uint32_t way) const
{
// Get relevant bits of the addr
Addr addr1 = bits<Addr>(addr, msbShift, 0);
@@ -146,7 +146,7 @@ SkewedAssoc::deskew(const Addr addr, const unsigned way) const
// If we have more than NUM_SKEWING_FUNCTIONS ways, unpile the hashes
if (way >= NUM_SKEWING_FUNCTIONS) {
- for (int i = 0; i < way/NUM_SKEWING_FUNCTIONS; i++) {
+ for (uint32_t i = 0; i < way/NUM_SKEWING_FUNCTIONS; i++) {
addr1 = dehash(addr1);
}
}
@@ -190,58 +190,37 @@ SkewedAssoc::deskew(const Addr addr, const unsigned way) const
}
}
-unsigned
-SkewedAssoc::extractSet(Addr addr, unsigned way) const
+uint32_t
+SkewedAssociative::extractSet(const Addr addr, const uint32_t way) const
{
return skew(addr >> setShift, way) & setMask;
}
Addr
-SkewedAssoc::regenerateBlkAddr(const CacheBlk* blk) const
+SkewedAssociative::regenerateAddr(const Addr tag,
+ const ReplaceableEntry* entry) const
{
- const Addr addr = (blk->tag << (msbShift + 1)) | blk->getSet();
- const Addr set = deskew(addr, blk->getWay()) & setMask;
- return (blk->tag << tagShift) | (set << setShift);
+ const Addr addr_set = (tag << (msbShift + 1)) | entry->getSet();
+ return (tag << tagShift) |
+ ((deskew(addr_set, entry->getWay()) & setMask) << setShift);
}
std::vector<ReplaceableEntry*>
-SkewedAssoc::getPossibleLocations(const Addr addr) const
+SkewedAssociative::getPossibleEntries(const Addr addr) const
{
- std::vector<ReplaceableEntry*> locations;
+ std::vector<ReplaceableEntry*> entries;
// Parse all ways
- for (int way = 0; way < assoc; ++way) {
+ for (uint32_t way = 0; way < assoc; ++way) {
// Apply hash to get set, and get way entry in it
- locations.push_back(sets[extractSet(addr, way)][way]);
- }
-
- return locations;
-}
-
-CacheBlk*
-SkewedAssoc::findBlock(Addr addr, bool is_secure) const
-{
- // Extract block tag
- Addr tag = extractTag(addr);
-
- // Find possible locations for the given address
- std::vector<ReplaceableEntry*> locations = getPossibleLocations(addr);
-
- // Search for block
- for (const auto& location : locations) {
- CacheBlk* blk = static_cast<CacheBlk*>(location);
- if ((blk->tag == tag) && blk->isValid() &&
- (blk->isSecure() == is_secure)) {
- return blk;
- }
+ entries.push_back(sets[extractSet(addr, way)][way]);
}
- // Did not find block
- return nullptr;
+ return entries;
}
-SkewedAssoc *
-SkewedAssocParams::create()
+SkewedAssociative *
+SkewedAssociativeParams::create()
{
- return new SkewedAssoc(this);
+ return new SkewedAssociative(this);
}
diff --git a/src/mem/cache/tags/skewed_assoc.hh b/src/mem/cache/tags/indexing_policies/skewed_associative.hh
index 597c32fcd..de3e57963 100644
--- a/src/mem/cache/tags/skewed_assoc.hh
+++ b/src/mem/cache/tags/indexing_policies/skewed_associative.hh
@@ -30,28 +30,45 @@
/**
* @file
- * Declaration of a skewed associative tag store.
+ * Declaration of a skewed associative indexing policy.
*/
-#ifndef __MEM_CACHE_TAGS_SKEWED_ASSOC_HH__
-#define __MEM_CACHE_TAGS_SKEWED_ASSOC_HH__
+#ifndef __MEM_CACHE_INDEXING_POLICIES_SKEWED_ASSOCIATIVE_HH__
+#define __MEM_CACHE_INDEXING_POLICIES_SKEWED_ASSOCIATIVE_HH__
-#include "mem/cache/blk.hh"
-#include "mem/cache/tags/base_set_assoc.hh"
-#include "params/SkewedAssoc.hh"
+#include <vector>
+
+#include "mem/cache/tags/indexing_policies/base.hh"
+#include "params/SkewedAssociative.hh"
+
+class ReplaceableEntry;
/**
- * A SkewedAssoc cache tag store.
- * @sa \ref gem5MemorySystem "gem5 Memory System"
+ * A skewed associative indexing policy.
+ * @sa \ref gem5MemorySystem "gem5 Memory System"
*
- * The SkewedAssoc placement policy divides the cache into s sets of w
- * cache lines (ways). A cache line has a different set mapping for each way,
- * according to a skewing function.
+ * The skewed indexing policy has a variable mapping based on a hash function,
+ * so a value x can be mapped to different sets, based on the way being used.
+ *
+ * For example, let's assume address A maps to set 3 on way 0. It will likely
+ * have a different set for every other way. Visually, the possible locations
+ * of A are, for a table with 4 ways and 8 sets (arbitrarily chosen sets; these
+ * locations depend on A and the hashing function used):
+ * Way 0 1 2 3
+ * Set _ _ _ _
+ * 0 |_| |_| |X| |_|
+ * 1 |_| |_| |_| |X|
+ * 2 |_| |_| |_| |_|
+ * 3 |X| |_| |_| |_|
+ * 4 |_| |_| |_| |_|
+ * 5 |_| |X| |_| |_|
+ * 6 |_| |_| |_| |_|
+ * 7 |_| |_| |_| |_|
*
* If provided with an associativity higher than the number of skewing
* functions, the skewing functions of the extra ways might be sub-optimal.
*/
-class SkewedAssoc : public BaseSetAssoc
+class SkewedAssociative : public BaseIndexingPolicy
{
private:
/**
@@ -98,7 +115,7 @@ class SkewedAssoc : public BaseSetAssoc
* @param way The cache way, used to select a hash function.
* @return The skewed address.
*/
- Addr skew(const Addr addr, const unsigned way) const;
+ Addr skew(const Addr addr, const uint32_t way) const;
/**
* Address deskewing function (inverse of the skew function) of the given
@@ -109,7 +126,7 @@ class SkewedAssoc : public BaseSetAssoc
* @param way The cache way, used to select a hash function.
* @return The deskewed address.
*/
- Addr deskew(const Addr addr, const unsigned way) const;
+ Addr deskew(const Addr addr, const uint32_t way) const;
/**
* Apply a skewing function to calculate address' set given a way.
@@ -118,53 +135,43 @@ class SkewedAssoc : public BaseSetAssoc
* @param way The way to get the set from.
* @return The set index for given combination of address and way.
*/
- unsigned extractSet(Addr addr, unsigned way) const;
-
- protected:
- /**
- * Find all possible block locations for insertion and replacement of
- * an address. Should be called immediately before ReplacementPolicy's
- * findVictim() not to break cache resizing.
- * Returns blocks in all ways belonging to the set of the address.
- *
- * @param addr The addr to a find possible locations for.
- * @return The possible locations.
- */
- std::vector<ReplaceableEntry*> getPossibleLocations(const Addr addr) const
- override;
+ uint32_t extractSet(const Addr addr, const uint32_t way) const;
public:
/** Convenience typedef. */
- typedef SkewedAssocParams Params;
+ typedef SkewedAssociativeParams Params;
/**
- * Construct and initialize this tag store.
+ * Construct and initialize this policy.
*/
- SkewedAssoc(const Params *p);
+ SkewedAssociative(const Params *p);
/**
- * Destructor
+ * Destructor.
*/
- ~SkewedAssoc() {};
+ ~SkewedAssociative() {};
/**
- * Finds the given address in the cache, do not update replacement data.
- * i.e. This is a no-side-effect find of a block.
+ * Find all possible entries for insertion and replacement of an address.
+ * Should be called immediately before ReplacementPolicy's findVictim()
+ * not to break cache resizing.
*
- * @param addr The address to find.
- * @param is_secure True if the target memory space is secure.
- * @return Pointer to the cache block if found.
+ * @param addr The addr to a find possible entries for.
+ * @return The possible entries.
*/
- CacheBlk* findBlock(Addr addr, bool is_secure) const override;
+ std::vector<ReplaceableEntry*> getPossibleEntries(const Addr addr) const
+ override;
/**
- * Regenerate the block address from the tag, set and way. Uses the
- * inverse of the skewing function.
+ * Regenerate an entry's address from its tag and assigned set and way.
+ * Uses the inverse of the skewing function.
*
- * @param block The block.
- * @return the block address.
+ * @param tag The tag bits.
+ * @param entry The entry.
+ * @return the entry's address.
*/
- Addr regenerateBlkAddr(const CacheBlk* blk) const override;
+ Addr regenerateAddr(const Addr tag, const ReplaceableEntry* entry) const
+ override;
};
-#endif //__MEM_CACHE_TAGS_SKEWED_ASSOC_HH__
+#endif //__MEM_CACHE_INDEXING_POLICIES_SKEWED_ASSOCIATIVE_HH__
diff --git a/src/mem/cache/tags/sector_tags.cc b/src/mem/cache/tags/sector_tags.cc
index 90b31b64b..f256807e2 100644
--- a/src/mem/cache/tags/sector_tags.cc
+++ b/src/mem/cache/tags/sector_tags.cc
@@ -30,7 +30,7 @@
/**
* @file
- * Definitions of a base set associative sector tag store.
+ * Definitions of a sector tag store.
*/
#include "mem/cache/tags/sector_tags.hh"
@@ -45,28 +45,22 @@
#include "debug/CacheRepl.hh"
#include "mem/cache/base.hh"
#include "mem/cache/replacement_policies/base.hh"
+#include "mem/cache/tags/indexing_policies/base.hh"
SectorTags::SectorTags(const SectorTagsParams *p)
- : BaseTags(p), assoc(p->assoc), allocAssoc(p->assoc),
+ : BaseTags(p), allocAssoc(p->assoc),
sequentialAccess(p->sequential_access),
replacementPolicy(p->replacement_policy),
numBlocksPerSector(p->num_blocks_per_sector),
- numSectors(numBlocks / p->num_blocks_per_sector),
- numSets(numSectors / p->assoc),
- blks(numBlocks), secBlks(numSectors), sets(numSets),
- sectorShift(floorLog2(blkSize)),
- setShift(sectorShift + floorLog2(numBlocksPerSector)),
- tagShift(setShift + floorLog2(numSets)),
- sectorMask(numBlocksPerSector - 1), setMask(numSets - 1)
+ numSectors(numBlocks / p->num_blocks_per_sector), blks(numBlocks),
+ secBlks(numSectors), sectorShift(floorLog2(blkSize)),
+ sectorMask(numBlocksPerSector - 1)
{
// Check parameters
fatal_if(blkSize < 4 || !isPowerOf2(blkSize),
"Block size must be at least 4 and a power of 2");
- fatal_if(!isPowerOf2(numSets),
- "# of sets must be non-zero and a power of 2");
fatal_if(!isPowerOf2(numBlocksPerSector),
"# of blocks per sector must be non-zero and a power of 2");
- fatal_if(assoc <= 0, "associativity must be greater than zero");
}
void
@@ -75,54 +69,43 @@ SectorTags::init(BaseCache* cache)
// Set parent cache
setCache(cache);
- // Initialize all sets
- unsigned sec_blk_index = 0; // index into sector blks array
+ // Initialize all blocks
unsigned blk_index = 0; // index into blks array
- for (unsigned i = 0; i < numSets; ++i) {
- sets[i].resize(assoc);
+ for (unsigned sec_blk_index = 0; sec_blk_index < numSectors;
+ sec_blk_index++)
+ {
+ // Locate next cache sector
+ SectorBlk* sec_blk = &secBlks[sec_blk_index];
- // Initialize all sectors in this set
- for (unsigned j = 0; j < assoc; ++j) {
- // Select block within the set to be linked
- SectorBlk*& sec_blk = sets[i][j];
-
- // Locate next cache sector
- sec_blk = &secBlks[sec_blk_index];
-
- // Associate a replacement data entry to the sector
- sec_blk->replacementData = replacementPolicy->instantiateEntry();
+ // Link block to indexing policy
+ indexingPolicy->setEntry(sec_blk, sec_blk_index);
- // Set its index
- sec_blk->setPosition(i, j);
+ // Associate a replacement data entry to the sector
+ sec_blk->replacementData = replacementPolicy->instantiateEntry();
- // Initialize all blocks in this sector
- sec_blk->blks.resize(numBlocksPerSector);
- for (unsigned k = 0; k < numBlocksPerSector; ++k){
- // Select block within the set to be linked
- SectorSubBlk*& blk = sec_blk->blks[k];
-
- // Locate next cache block
- blk = &blks[blk_index];
+ // Initialize all blocks in this sector
+ sec_blk->blks.resize(numBlocksPerSector);
+ for (unsigned k = 0; k < numBlocksPerSector; ++k){
+ // Select block within the set to be linked
+ SectorSubBlk*& blk = sec_blk->blks[k];
- // Associate a data chunk to the block
- blk->data = &dataBlks[blkSize*blk_index];
+ // Locate next cache block
+ blk = &blks[blk_index];
- // Associate sector block to this block
- blk->setSectorBlock(sec_blk);
+ // Associate a data chunk to the block
+ blk->data = &dataBlks[blkSize*blk_index];
- // Associate the sector replacement data to this block
- blk->replacementData = sec_blk->replacementData;
+ // Associate sector block to this block
+ blk->setSectorBlock(sec_blk);
- // Set its index and sector offset
- blk->setPosition(i, j);
- blk->setSectorOffset(k);
+ // Associate the sector replacement data to this block
+ blk->replacementData = sec_blk->replacementData;
- // Update block index
- ++blk_index;
- }
+ // Set its index and sector offset
+ blk->setSectorOffset(k);
- // Update sector block index
- ++sec_blk_index;
+ // Update block index
+ ++blk_index;
}
}
}
@@ -196,16 +179,6 @@ SectorTags::accessBlock(Addr addr, bool is_secure, Cycles &lat)
return blk;
}
-std::vector<ReplaceableEntry*>
-SectorTags::getPossibleLocations(const Addr addr) const
-{
- std::vector<ReplaceableEntry*> locations;
- for (const auto& blk : sets[extractSet(addr)]) {
- locations.push_back(static_cast<ReplaceableEntry*>(blk));
- }
- return locations;
-}
-
void
SectorTags::insertBlock(const Addr addr, const bool is_secure,
const int src_master_ID, const uint32_t task_ID,
@@ -243,12 +216,12 @@ SectorTags::findBlock(Addr addr, bool is_secure) const
// due to sectors being composed of contiguous-address entries
const Addr offset = extractSectorOffset(addr);
- // Find all possible sector locations for the given address
- const std::vector<ReplaceableEntry*> locations =
- getPossibleLocations(addr);
+ // Find all possible sector entries that may contain the given address
+ const std::vector<ReplaceableEntry*> entries =
+ indexingPolicy->getPossibleEntries(addr);
// Search for block
- for (const auto& sector : locations) {
+ for (const auto& sector : entries) {
auto blk = static_cast<SectorBlk*>(sector)->blks[offset];
if (blk->getTag() == tag && blk->isValid() &&
blk->isSecure() == is_secure) {
@@ -260,24 +233,18 @@ SectorTags::findBlock(Addr addr, bool is_secure) const
return nullptr;
}
-ReplaceableEntry*
-SectorTags::findBlockBySetAndWay(int set, int way) const
-{
- return sets[set][way];
-}
-
CacheBlk*
SectorTags::findVictim(Addr addr, const bool is_secure,
std::vector<CacheBlk*>& evict_blks) const
{
- // Get all possible locations of this sector
- const std::vector<ReplaceableEntry*> sector_locations =
- getPossibleLocations(addr);
+ // Get possible entries to be victimized
+ const std::vector<ReplaceableEntry*> sector_entries =
+ indexingPolicy->getPossibleEntries(addr);
// Check if the sector this address belongs to has been allocated
Addr tag = extractTag(addr);
SectorBlk* victim_sector = nullptr;
- for (const auto& sector : sector_locations) {
+ for (const auto& sector : sector_entries) {
SectorBlk* sector_blk = static_cast<SectorBlk*>(sector);
if ((tag == sector_blk->getTag()) && sector_blk->isValid() &&
(is_secure == sector_blk->isSecure())){
@@ -290,10 +257,10 @@ SectorTags::findVictim(Addr addr, const bool is_secure,
if (victim_sector == nullptr){
// Choose replacement victim from replacement candidates
victim_sector = static_cast<SectorBlk*>(replacementPolicy->getVictim(
- sector_locations));
+ sector_entries));
}
- // Get the location of the victim block within the sector
+ // Get the entry of the victim block within the sector
SectorSubBlk* victim = victim_sector->blks[extractSectorOffset(addr)];
// Get evicted blocks. Blocks are only evicted if the sectors mismatch and
@@ -317,18 +284,6 @@ SectorTags::findVictim(Addr addr, const bool is_secure,
return victim;
}
-Addr
-SectorTags::extractTag(Addr addr) const
-{
- return addr >> tagShift;
-}
-
-int
-SectorTags::extractSet(Addr addr) const
-{
- return (addr >> setShift) & setMask;
-}
-
int
SectorTags::extractSectorOffset(Addr addr) const
{
@@ -339,9 +294,9 @@ Addr
SectorTags::regenerateBlkAddr(const CacheBlk* blk) const
{
const SectorSubBlk* blk_cast = static_cast<const SectorSubBlk*>(blk);
- const Addr set = blk_cast->getSectorBlock()->getSet() << setShift;
- return ((blk_cast->getTag() << tagShift) | set |
- ((Addr)blk_cast->getSectorOffset() << sectorShift));
+ const SectorBlk* sec_blk = blk_cast->getSectorBlock();
+ const Addr sec_addr = indexingPolicy->regenerateAddr(blk->tag, sec_blk);
+ return sec_addr | ((Addr)blk_cast->getSectorOffset() << sectorShift);
}
void
@@ -366,5 +321,8 @@ SectorTags::anyBlk(std::function<bool(CacheBlk &)> visitor)
SectorTags *
SectorTagsParams::create()
{
+ // There must be a indexing policy
+ fatal_if(!indexing_policy, "An indexing policy is required");
+
return new SectorTags(this);
}
diff --git a/src/mem/cache/tags/sector_tags.hh b/src/mem/cache/tags/sector_tags.hh
index c3c3bc8f9..518ab28a9 100644
--- a/src/mem/cache/tags/sector_tags.hh
+++ b/src/mem/cache/tags/sector_tags.hh
@@ -30,7 +30,7 @@
/**
* @file
- * Declaration of a sector set associative tag store.
+ * Declaration of a sector tag store.
*/
#ifndef __MEM_CACHE_TAGS_SECTOR_TAGS_HH__
@@ -58,11 +58,6 @@ class ReplaceableEntry;
class SectorTags : public BaseTags
{
protected:
- /** Typedef the set type used in this tag store. */
- typedef std::vector<SectorBlk*> SetType;
-
- /** The associativity of the cache. */
- const unsigned assoc;
/** The allocatable associativity of the cache (alloc mask). */
unsigned allocAssoc;
@@ -77,40 +72,19 @@ class SectorTags : public BaseTags
/** The number of sectors in the cache. */
const unsigned numSectors;
- /** The number of sets in the cache. */
- const unsigned numSets;
/** The cache blocks. */
std::vector<SectorSubBlk> blks;
/** The cache sector blocks. */
std::vector<SectorBlk> secBlks;
- /** The cache sets. */
- std::vector<SetType> sets;
- // Organization of an address: Tag | Set # | Sector Offset # | Offset #
+ // Organization of an address:
+ // Tag | Placement Location | Sector Offset # | Offset #
/** The amount to shift the address to get the sector tag. */
const int sectorShift;
- /** The amount to shift the address to get the set. */
- const int setShift;
- /** The amount to shift the address to get the tag. */
- const int tagShift;
/** Mask out all bits that aren't part of the sector tag. */
const unsigned sectorMask;
- /** Mask out all bits that aren't part of the set index. */
- const unsigned setMask;
-
- /**
- * Find all possible block locations for insertion and replacement of
- * an address. Should be called immediately before ReplacementPolicy's
- * findVictim() not to break cache resizing.
- * Returns sector blocks in all ways belonging to the set of the address.
- *
- * @param addr The addr to a find possible locations for.
- * @return The possible locations.
- */
- std::vector<ReplaceableEntry*> getPossibleLocations(const Addr addr) const
- override;
public:
/** Convenience typedef. */
@@ -178,15 +152,6 @@ class SectorTags : public BaseTags
CacheBlk* findBlock(Addr addr, bool is_secure) const override;
/**
- * Find a sector block given set and way.
- *
- * @param set The set of the block.
- * @param way The way of the block.
- * @return The block.
- */
- ReplaceableEntry* findBlockBySetAndWay(int set, int way) const override;
-
- /**
* Find replacement victim based on address.
*
* @param addr Address to find a victim for.
@@ -198,22 +163,6 @@ class SectorTags : public BaseTags
std::vector<CacheBlk*>& evict_blks) const override;
/**
- * Generate the sector tag from the given address.
- *
- * @param addr The address to get the sector tag from.
- * @return The sector tag of the address.
- */
- Addr extractTag(Addr addr) const override;
-
- /**
- * 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;
-
- /**
* Calculate a block's offset in a sector from the address.
*
* @param addr The address to get the offset from.
@@ -222,7 +171,7 @@ class SectorTags : public BaseTags
int extractSectorOffset(Addr addr) const;
/**
- * Regenerate the block address from the tag and set.
+ * Regenerate the block address from the tag and location.
*
* @param block The block.
* @return the block address.