diff --git a/src/mem/cache/prefetch/stride.hh b/src/mem/cache/prefetch/stride.hh index 81bf8da651..dda694938a 100644 --- a/src/mem/cache/prefetch/stride.hh +++ b/src/mem/cache/prefetch/stride.hh @@ -63,7 +63,6 @@ namespace gem5 { -class BaseIndexingPolicy; namespace replacement_policy { class Base; diff --git a/src/mem/cache/tags/base.hh b/src/mem/cache/tags/base.hh index d700418937..8f79f26d4a 100644 --- a/src/mem/cache/tags/base.hh +++ b/src/mem/cache/tags/base.hh @@ -56,6 +56,7 @@ #include "base/statistics.hh" #include "base/types.hh" #include "mem/cache/cache_blk.hh" +#include "mem/cache/tags/indexing_policies/base.hh" #include "mem/packet.hh" #include "params/BaseTags.hh" #include "sim/clocked_object.hh" @@ -64,7 +65,6 @@ namespace gem5 { class System; -class IndexingPolicy; class ReplaceableEntry; /** diff --git a/src/mem/cache/tags/indexing_policies/IndexingPolicies.py b/src/mem/cache/tags/indexing_policies/IndexingPolicies.py index 83bc15cb5c..437f903ca8 100644 --- a/src/mem/cache/tags/indexing_policies/IndexingPolicies.py +++ b/src/mem/cache/tags/indexing_policies/IndexingPolicies.py @@ -1,3 +1,16 @@ +# -*- mode:python -*- +# Copyright (c) 2024 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) 2018 Inria # All rights reserved. # @@ -32,8 +45,9 @@ from m5.SimObject import SimObject class BaseIndexingPolicy(SimObject): type = "BaseIndexingPolicy" abstract = True - cxx_class = "gem5::BaseIndexingPolicy" + cxx_class = "gem5::IndexingPolicyTemplate" cxx_header = "mem/cache/tags/indexing_policies/base.hh" + cxx_template_params = ["class Types"] # Get the size from the parent (cache) size = Param.MemorySize(Parent.size, "capacity in bytes") diff --git a/src/mem/cache/tags/indexing_policies/SConscript b/src/mem/cache/tags/indexing_policies/SConscript index 60d89128dd..eadf6152c7 100644 --- a/src/mem/cache/tags/indexing_policies/SConscript +++ b/src/mem/cache/tags/indexing_policies/SConscript @@ -30,6 +30,5 @@ Import('*') SimObject('IndexingPolicies.py', sim_objects=[ 'BaseIndexingPolicy', 'SetAssociative', 'SkewedAssociative']) -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 deleted file mode 100644 index f4f71554b5..0000000000 --- a/src/mem/cache/tags/indexing_policies/base.cc +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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. - */ - -/** - * @file - * Definitions of a common framework for indexing policies. - */ - -#include "mem/cache/tags/indexing_policies/base.hh" - -#include - -#include "base/intmath.hh" -#include "base/logging.hh" -#include "mem/cache/replacement_policies/replaceable_entry.hh" - -namespace gem5 -{ - -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); -} - -} // namespace gem5 diff --git a/src/mem/cache/tags/indexing_policies/base.hh b/src/mem/cache/tags/indexing_policies/base.hh index 6cd3e72894..72c22dbdcf 100644 --- a/src/mem/cache/tags/indexing_policies/base.hh +++ b/src/mem/cache/tags/indexing_policies/base.hh @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 Inria - * Copyright (c) 2012-2014,2017 ARM Limited + * Copyright (c) 2012-2014,2017,2024 Arm Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -49,23 +49,32 @@ #include +#include "base/intmath.hh" +#include "base/logging.hh" +#include "mem/cache/replacement_policies/replaceable_entry.hh" #include "params/BaseIndexingPolicy.hh" #include "sim/sim_object.hh" namespace gem5 { -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" + * @tparam Types the Types template parameter shall contain the following type + * traits: + * - KeyType = The key/lookup data type + * - Params = The indexing policy Param type */ -class BaseIndexingPolicy : public SimObject +template +class IndexingPolicyTemplate : public SimObject { protected: + using KeyType = typename Types::KeyType; + using Params = typename Types::Params; + /** * The associativity. */ @@ -97,20 +106,29 @@ class BaseIndexingPolicy : public SimObject const int tagShift; public: - /** - * Convenience typedef. - */ - typedef BaseIndexingPolicyParams Params; - /** * Construct and initialize this policy. */ - BaseIndexingPolicy(const Params &p); + IndexingPolicyTemplate(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); + } + } /** * Destructor. */ - ~BaseIndexingPolicy() {}; + ~IndexingPolicyTemplate() {}; /** * Associate a pointer to an entry to its physical counterpart. @@ -118,7 +136,23 @@ class BaseIndexingPolicy : public SimObject * @param entry The entry pointer. * @param index An unique index for the entry. */ - void setEntry(ReplaceableEntry* entry, const uint64_t index); + void + 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); + } /** * Get an entry based on its set and way. All entries must have been set @@ -128,7 +162,11 @@ class BaseIndexingPolicy : public SimObject * @param way The way of the desired entry. * @return entry The entry pointer. */ - ReplaceableEntry* getEntry(const uint32_t set, const uint32_t way) const; + ReplaceableEntry* + getEntry(const uint32_t set, const uint32_t way) const + { + return sets[set][way]; + } /** * Generate the tag from the given address. @@ -136,7 +174,12 @@ class BaseIndexingPolicy : public SimObject * @param addr The address to get the tag from. * @return The tag of the address. */ - virtual Addr extractTag(const Addr addr) const; + virtual Addr + extractTag(const Addr addr) const + { + return (addr >> tagShift); + } + /** * Find all possible entries for insertion and replacement of an address. @@ -146,7 +189,7 @@ class BaseIndexingPolicy : public SimObject * @param addr The addr to a find possible entries for. * @return The possible entries. */ - virtual std::vector getPossibleEntries(const Addr addr) + virtual std::vector getPossibleEntries(const KeyType &key) const = 0; /** @@ -156,10 +199,20 @@ class BaseIndexingPolicy : public SimObject * @param entry The entry. * @return the entry's original address. */ - virtual Addr regenerateAddr(const Addr tag, const ReplaceableEntry* entry) - const = 0; + virtual Addr regenerateAddr(const KeyType &key, + const ReplaceableEntry* entry) const = 0; }; +class AddrTypes +{ + public: + using KeyType = Addr; + using Params = BaseIndexingPolicyParams; +}; + +using BaseIndexingPolicy = IndexingPolicyTemplate; +template class IndexingPolicyTemplate; + } // namespace gem5 #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 index d41a8851d6..36011f10ef 100644 --- a/src/mem/cache/tags/indexing_policies/set_associative.cc +++ b/src/mem/cache/tags/indexing_policies/set_associative.cc @@ -63,14 +63,14 @@ SetAssociative::extractSet(const Addr addr) const } Addr -SetAssociative::regenerateAddr(const Addr tag, const ReplaceableEntry* entry) - const +SetAssociative::regenerateAddr(const Addr &tag, + const ReplaceableEntry* entry) const { return (tag << tagShift) | (entry->getSet() << setShift); } std::vector -SetAssociative::getPossibleEntries(const Addr addr) const +SetAssociative::getPossibleEntries(const Addr &addr) const { return sets[extractSet(addr)]; } diff --git a/src/mem/cache/tags/indexing_policies/set_associative.hh b/src/mem/cache/tags/indexing_policies/set_associative.hh index c47848a895..c93ef12fdb 100644 --- a/src/mem/cache/tags/indexing_policies/set_associative.hh +++ b/src/mem/cache/tags/indexing_policies/set_associative.hh @@ -115,7 +115,7 @@ class SetAssociative : public BaseIndexingPolicy * @param addr The addr to a find possible entries for. * @return The possible entries. */ - std::vector getPossibleEntries(const Addr addr) const + std::vector getPossibleEntries(const Addr &addr) const override; /** @@ -125,8 +125,8 @@ class SetAssociative : public BaseIndexingPolicy * @param entry The entry. * @return the entry's original addr value. */ - Addr regenerateAddr(const Addr tag, const ReplaceableEntry* entry) const - override; + Addr regenerateAddr(const Addr &tag, + const ReplaceableEntry* entry) const override; }; } // namespace gem5 diff --git a/src/mem/cache/tags/indexing_policies/skewed_associative.cc b/src/mem/cache/tags/indexing_policies/skewed_associative.cc index bd6573bcf6..76e7acabca 100644 --- a/src/mem/cache/tags/indexing_policies/skewed_associative.cc +++ b/src/mem/cache/tags/indexing_policies/skewed_associative.cc @@ -198,7 +198,7 @@ SkewedAssociative::extractSet(const Addr addr, const uint32_t way) const } Addr -SkewedAssociative::regenerateAddr(const Addr tag, +SkewedAssociative::regenerateAddr(const Addr &tag, const ReplaceableEntry* entry) const { const Addr addr_set = (tag << (msbShift + 1)) | entry->getSet(); @@ -207,7 +207,7 @@ SkewedAssociative::regenerateAddr(const Addr tag, } std::vector -SkewedAssociative::getPossibleEntries(const Addr addr) const +SkewedAssociative::getPossibleEntries(const Addr &addr) const { std::vector entries; diff --git a/src/mem/cache/tags/indexing_policies/skewed_associative.hh b/src/mem/cache/tags/indexing_policies/skewed_associative.hh index 887087e6ac..9e77aa91b7 100644 --- a/src/mem/cache/tags/indexing_policies/skewed_associative.hh +++ b/src/mem/cache/tags/indexing_policies/skewed_associative.hh @@ -160,7 +160,7 @@ class SkewedAssociative : public BaseIndexingPolicy * @param addr The addr to a find possible entries for. * @return The possible entries. */ - std::vector getPossibleEntries(const Addr addr) const + std::vector getPossibleEntries(const Addr &addr) const override; /** @@ -171,8 +171,8 @@ class SkewedAssociative : public BaseIndexingPolicy * @param entry The entry. * @return the entry's address. */ - Addr regenerateAddr(const Addr tag, const ReplaceableEntry* entry) const - override; + Addr regenerateAddr(const Addr &tag, + const ReplaceableEntry* entry) const override; }; } // namespace gem5