From: David Hashe Date: Mon, 20 Jul 2015 14:15:18 +0000 (-0500) Subject: ruby: initialize replacement policies with their own simobjs X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1850ed410fc85d7ac367dc7b378e5509d62ed900;p=gem5.git ruby: initialize replacement policies with their own simobjs this is in preparation for other replacement policies that take additional parameters. --- diff --git a/configs/ruby/MESI_Three_Level.py b/configs/ruby/MESI_Three_Level.py index 42b5119da..60001864c 100644 --- a/configs/ruby/MESI_Three_Level.py +++ b/configs/ruby/MESI_Three_Level.py @@ -95,10 +95,12 @@ def create_system(options, full_system, system, dma_ports, ruby_system): # First create the Ruby objects associated with this cpu # l0i_cache = L0Cache(size = '4096B', assoc = 1, is_icache = True, - start_index_bit = block_size_bits, replacement_policy="LRU") + start_index_bit = block_size_bits, + replacement_policy = LRUReplacementPolicy()) l0d_cache = L0Cache(size = '4096B', assoc = 1, is_icache = False, - start_index_bit = block_size_bits, replacement_policy="LRU") + start_index_bit = block_size_bits, + replacement_policy = LRUReplacementPolicy()) l0_cntrl = L0Cache_Controller(version = i*num_cpus_per_cluster + j, Icache = l0i_cache, Dcache = l0d_cache, diff --git a/src/mem/ruby/structures/AbstractReplacementPolicy.cc b/src/mem/ruby/structures/AbstractReplacementPolicy.cc new file mode 100644 index 000000000..fbcce6e2d --- /dev/null +++ b/src/mem/ruby/structures/AbstractReplacementPolicy.cc @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013 Advanced Micro Devices, Inc + * 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. + * + * Author: Derek Hower + */ + +#include "mem/ruby/structures/AbstractReplacementPolicy.hh" + +AbstractReplacementPolicy::AbstractReplacementPolicy(const Params * p) + : SimObject(p) +{ + m_num_sets = p->size/p->block_size/p->assoc; + m_assoc = p->assoc; + m_last_ref_ptr = new Tick*[m_num_sets]; + for(unsigned i = 0; i < m_num_sets; i++){ + m_last_ref_ptr[i] = new Tick[m_assoc]; + for(unsigned j = 0; j < m_assoc; j++){ + m_last_ref_ptr[i][j] = 0; + } + } +} + +AbstractReplacementPolicy * +ReplacementPolicyParams::create() +{ + fatal("Cannot create an AbstractReplacementPolicy"); + return NULL; +} + + + +AbstractReplacementPolicy::~AbstractReplacementPolicy() +{ + if (m_last_ref_ptr != NULL){ + for (unsigned i = 0; i < m_num_sets; i++){ + if (m_last_ref_ptr[i] != NULL){ + delete[] m_last_ref_ptr[i]; + } + } + delete[] m_last_ref_ptr; + } +} + +Tick +AbstractReplacementPolicy::getLastAccess(int64 set, int64 way) +{ + return m_last_ref_ptr[set][way]; +} diff --git a/src/mem/ruby/structures/AbstractReplacementPolicy.hh b/src/mem/ruby/structures/AbstractReplacementPolicy.hh index 5601d8537..d007c98c8 100644 --- a/src/mem/ruby/structures/AbstractReplacementPolicy.hh +++ b/src/mem/ruby/structures/AbstractReplacementPolicy.hh @@ -30,11 +30,15 @@ #define __MEM_RUBY_STRUCTURES_ABSTRACTREPLACEMENTPOLICY_HH__ #include "base/types.hh" +#include "mem/ruby/common/TypeDefines.hh" +#include "params/ReplacementPolicy.hh" +#include "sim/sim_object.hh" -class AbstractReplacementPolicy +class AbstractReplacementPolicy : public SimObject { public: - AbstractReplacementPolicy(int64 num_sets, int64 assoc); + typedef ReplacementPolicyParams Params; + AbstractReplacementPolicy(const Params * p); virtual ~AbstractReplacementPolicy(); /* touch a block. a.k.a. update timestamp */ @@ -46,44 +50,12 @@ class AbstractReplacementPolicy /* get the time of the last access */ Tick getLastAccess(int64 set, int64 way); + virtual bool useOccupancy() const { return false; } + protected: unsigned m_num_sets; /** total number of sets */ unsigned m_assoc; /** set associativity */ Tick **m_last_ref_ptr; /** timestamp of last reference */ }; -inline -AbstractReplacementPolicy::AbstractReplacementPolicy(int64 num_sets, - int64 assoc) -{ - m_num_sets = num_sets; - m_assoc = assoc; - m_last_ref_ptr = new Tick*[m_num_sets]; - for(unsigned i = 0; i < m_num_sets; i++){ - m_last_ref_ptr[i] = new Tick[m_assoc]; - for(unsigned j = 0; j < m_assoc; j++){ - m_last_ref_ptr[i][j] = 0; - } - } -} - -inline -AbstractReplacementPolicy::~AbstractReplacementPolicy() -{ - if (m_last_ref_ptr != NULL){ - for (unsigned i = 0; i < m_num_sets; i++){ - if (m_last_ref_ptr[i] != NULL){ - delete[] m_last_ref_ptr[i]; - } - } - delete[] m_last_ref_ptr; - } -} - -inline Tick -AbstractReplacementPolicy::getLastAccess(int64 set, int64 way) -{ - return m_last_ref_ptr[set][way]; -} - #endif // __MEM_RUBY_STRUCTURES_ABSTRACTREPLACEMENTPOLICY_HH__ diff --git a/src/mem/ruby/structures/Cache.py b/src/mem/ruby/structures/Cache.py index 3acec32cf..7f26e659f 100644 --- a/src/mem/ruby/structures/Cache.py +++ b/src/mem/ruby/structures/Cache.py @@ -29,6 +29,7 @@ from m5.params import * from m5.proxy import * +from PseudoLRUReplacementPolicy import PseudoLRUReplacementPolicy from m5.SimObject import SimObject class RubyCache(SimObject): @@ -38,7 +39,8 @@ class RubyCache(SimObject): size = Param.MemorySize("capacity in bytes"); latency = Param.Cycles(""); assoc = Param.Int(""); - replacement_policy = Param.String("PSEUDO_LRU", ""); + replacement_policy = Param.ReplacementPolicy(PseudoLRUReplacementPolicy(), + "") start_index_bit = Param.Int(6, "index start, default 6 for 64-byte line"); is_icache = Param.Bool(False, "is instruction only cache"); diff --git a/src/mem/ruby/structures/CacheMemory.cc b/src/mem/ruby/structures/CacheMemory.cc index 0576c4b33..047c024c9 100644 --- a/src/mem/ruby/structures/CacheMemory.cc +++ b/src/mem/ruby/structures/CacheMemory.cc @@ -61,7 +61,7 @@ CacheMemory::CacheMemory(const Params *p) m_cache_size = p->size; m_latency = p->latency; m_cache_assoc = p->assoc; - m_policy = p->replacement_policy; + m_replacementPolicy_ptr = p->replacement_policy; m_start_index_bit = p->start_index_bit; m_is_instruction_only_cache = p->is_icache; m_resource_stalls = p->resourceStalls; @@ -76,15 +76,6 @@ CacheMemory::init() m_cache_num_set_bits = floorLog2(m_cache_num_sets); assert(m_cache_num_set_bits > 0); - if (m_policy == "PSEUDO_LRU") - m_replacementPolicy_ptr = - new PseudoLRUPolicy(m_cache_num_sets, m_cache_assoc); - else if (m_policy == "LRU") - m_replacementPolicy_ptr = - new LRUPolicy(m_cache_num_sets, m_cache_assoc); - else - assert(false); - m_cache.resize(m_cache_num_sets); for (int i = 0; i < m_cache_num_sets; i++) { m_cache[i].resize(m_cache_assoc); diff --git a/src/mem/ruby/structures/CacheMemory.hh b/src/mem/ruby/structures/CacheMemory.hh index 647520566..a777538b2 100644 --- a/src/mem/ruby/structures/CacheMemory.hh +++ b/src/mem/ruby/structures/CacheMemory.hh @@ -40,9 +40,8 @@ #include "mem/ruby/common/DataBlock.hh" #include "mem/ruby/slicc_interface/AbstractCacheEntry.hh" #include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh" +#include "mem/ruby/structures/AbstractReplacementPolicy.hh" #include "mem/ruby/structures/BankedArray.hh" -#include "mem/ruby/structures/LRUPolicy.hh" -#include "mem/ruby/structures/PseudoLRUPolicy.hh" #include "mem/ruby/system/CacheRecorder.hh" #include "params/RubyCache.hh" #include "sim/sim_object.hh" @@ -163,7 +162,6 @@ class CacheMemory : public SimObject BankedArray tagArray; int m_cache_size; - std::string m_policy; int m_cache_num_sets; int m_cache_num_set_bits; int m_cache_assoc; diff --git a/src/mem/ruby/structures/LRUPolicy.cc b/src/mem/ruby/structures/LRUPolicy.cc new file mode 100644 index 000000000..a1e3b277e --- /dev/null +++ b/src/mem/ruby/structures/LRUPolicy.cc @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013 Advanced Micro Devices, Inc + * 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. + * + * Author: Derek Hower + */ + +#include "mem/ruby/structures/LRUPolicy.hh" + + + +LRUPolicy::LRUPolicy(const Params * p) + : AbstractReplacementPolicy(p) +{ +} + + +LRUPolicy::~LRUPolicy() +{ +} + +LRUPolicy * +LRUReplacementPolicyParams::create() +{ + return new LRUPolicy(this); +} + + +void +LRUPolicy::touch(int64 set, int64 index, Tick time) +{ + assert(index >= 0 && index < m_assoc); + assert(set >= 0 && set < m_num_sets); + + m_last_ref_ptr[set][index] = time; +} + +int64 +LRUPolicy::getVictim(int64 set) const +{ + Tick time, smallest_time; + int64 smallest_index; + + smallest_index = 0; + smallest_time = m_last_ref_ptr[set][0]; + + for (unsigned i = 0; i < m_assoc; i++) { + time = m_last_ref_ptr[set][i]; + + if (time < smallest_time) { + smallest_index = i; + smallest_time = time; + } + } + + return smallest_index; +} diff --git a/src/mem/ruby/structures/LRUPolicy.hh b/src/mem/ruby/structures/LRUPolicy.hh index c6203a4a6..9a9c9e3eb 100644 --- a/src/mem/ruby/structures/LRUPolicy.hh +++ b/src/mem/ruby/structures/LRUPolicy.hh @@ -30,66 +30,19 @@ #define __MEM_RUBY_STRUCTURES_LRUPOLICY_HH__ #include "mem/ruby/structures/AbstractReplacementPolicy.hh" +#include "params/LRUReplacementPolicy.hh" /* Simple true LRU replacement policy */ class LRUPolicy : public AbstractReplacementPolicy { public: - LRUPolicy(int64 num_sets, int64 assoc); + typedef LRUReplacementPolicyParams Params; + LRUPolicy(const Params * p); ~LRUPolicy(); void touch(int64 set, int64 way, Tick time); int64 getVictim(int64 set) const; }; -inline -LRUPolicy::LRUPolicy(int64 num_sets, int64 assoc) - : AbstractReplacementPolicy(num_sets, assoc) -{ -} - -inline -LRUPolicy::~LRUPolicy() -{ -} - -inline void -LRUPolicy::touch(int64 set, int64 index, Tick time) -{ - assert(index >= 0 && index < m_assoc); - assert(set >= 0 && set < m_num_sets); - - m_last_ref_ptr[set][index] = time; -} - -inline int64 -LRUPolicy::getVictim(int64 set) const -{ - // assert(m_assoc != 0); - Tick time, smallest_time; - int64 smallest_index; - - smallest_index = 0; - smallest_time = m_last_ref_ptr[set][0]; - - for (unsigned i = 0; i < m_assoc; i++) { - time = m_last_ref_ptr[set][i]; - // assert(m_cache[cacheSet][i].m_Permission != - // AccessPermission_NotPresent); - - if (time < smallest_time) { - smallest_index = i; - smallest_time = time; - } - } - - // DEBUG_EXPR(CACHE_COMP, MedPrio, cacheSet); - // DEBUG_EXPR(CACHE_COMP, MedPrio, smallest_index); - // DEBUG_EXPR(CACHE_COMP, MedPrio, m_cache[cacheSet][smallest_index]); - // DEBUG_EXPR(CACHE_COMP, MedPrio, *this); - - return smallest_index; -} - #endif // __MEM_RUBY_STRUCTURES_LRUPOLICY_HH__ diff --git a/src/mem/ruby/structures/LRUReplacementPolicy.py b/src/mem/ruby/structures/LRUReplacementPolicy.py new file mode 100644 index 000000000..2b4a263b7 --- /dev/null +++ b/src/mem/ruby/structures/LRUReplacementPolicy.py @@ -0,0 +1,41 @@ +# +# Copyright (c) 2013 Advanced Micro Devices, Inc +# 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. +# +# Author: Derek Hower + + + +from m5.params import * +from m5.SimObject import SimObject +from ReplacementPolicy import ReplacementPolicy + +class LRUReplacementPolicy(ReplacementPolicy): + type = 'LRUReplacementPolicy' + cxx_class = 'LRUPolicy' + cxx_header = 'mem/ruby/structures/LRUPolicy.hh' + + diff --git a/src/mem/ruby/structures/PseudoLRUPolicy.cc b/src/mem/ruby/structures/PseudoLRUPolicy.cc new file mode 100644 index 000000000..8eee0821b --- /dev/null +++ b/src/mem/ruby/structures/PseudoLRUPolicy.cc @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013 Advanced Micro Devices, Inc + * 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. + * + * Author: Derek Hower + */ + +#include "mem/ruby/structures/PseudoLRUPolicy.hh" + + + +PseudoLRUPolicy::PseudoLRUPolicy(const Params * p) + : AbstractReplacementPolicy(p) +{ + // associativity cannot exceed capacity of tree representation + assert(m_num_sets > 0 && + m_assoc > 1 && + m_assoc <= (int64) sizeof(uint64)*4); + + m_trees = NULL; + m_num_levels = 0; + + m_effective_assoc = 1; + while (m_effective_assoc < m_assoc) { + // effective associativity is ceiling power of 2 + m_effective_assoc <<= 1; + } + int tmp_assoc = m_effective_assoc; + while (true) { + tmp_assoc /= 2; + if(!tmp_assoc) break; + m_num_levels++; + } + assert(m_num_levels < sizeof(unsigned int)*4); + m_trees = new uint64[m_num_sets]; + for (unsigned i = 0; i < m_num_sets; i++) { + m_trees[i] = 0; + } +} + +PseudoLRUPolicy * +PseudoLRUReplacementPolicyParams::create() +{ + return new PseudoLRUPolicy(this); +} + + +PseudoLRUPolicy::~PseudoLRUPolicy() +{ + if (m_trees != NULL) + delete[] m_trees; +} + +void +PseudoLRUPolicy::touch(int64 set, int64 index, Tick time) +{ + assert(index >= 0 && index < m_assoc); + assert(set >= 0 && set < m_num_sets); + + int tree_index = 0; + int node_val; + for (int i = m_num_levels - 1; i >= 0; i--) { + node_val = (index >> i)&1; + if (node_val) + m_trees[set] |= node_val << tree_index; + else + m_trees[set] &= ~(1 << tree_index); + tree_index = node_val ? (tree_index*2)+2 : (tree_index*2)+1; + } + m_last_ref_ptr[set][index] = time; +} + +int64 +PseudoLRUPolicy::getVictim(int64 set) const +{ + int64 index = 0; + + int tree_index = 0; + int node_val; + for (unsigned i = 0; i < m_num_levels; i++){ + node_val = (m_trees[set] >> tree_index) & 1; + index += node_val ? 0 : (m_effective_assoc >> (i + 1)); + tree_index = node_val ? (tree_index * 2) + 1 : (tree_index * 2) + 2; + } + assert(index >= 0 && index < m_effective_assoc); + + /* return either the found index or the max possible index */ + /* NOTE: this is not a fair replacement when assoc is not a power of 2 */ + return (index > (m_assoc - 1)) ? m_assoc - 1 : index; +} diff --git a/src/mem/ruby/structures/PseudoLRUPolicy.hh b/src/mem/ruby/structures/PseudoLRUPolicy.hh index 9534fa781..fc5add8b1 100644 --- a/src/mem/ruby/structures/PseudoLRUPolicy.hh +++ b/src/mem/ruby/structures/PseudoLRUPolicy.hh @@ -1,5 +1,6 @@ /* * Copyright (c) 2007 Mark D. Hill and David A. Wood + * Copyright (c) 2013 Advanced Micro Devices, Inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,6 +31,7 @@ #define __MEM_RUBY_STRUCTURES_PSEUDOLRUPOLICY_HH__ #include "mem/ruby/structures/AbstractReplacementPolicy.hh" +#include "params/PseudoLRUReplacementPolicy.hh" /** * Implementation of tree-based pseudo-LRU replacement @@ -47,7 +49,8 @@ class PseudoLRUPolicy : public AbstractReplacementPolicy { public: - PseudoLRUPolicy(int64 num_sets, int64 assoc); + typedef PseudoLRUReplacementPolicyParams Params; + PseudoLRUPolicy(const Params * p); ~PseudoLRUPolicy(); void touch(int64 set, int64 way, Tick time); @@ -60,78 +63,4 @@ class PseudoLRUPolicy : public AbstractReplacementPolicy * trees, one for each set */ }; -inline -PseudoLRUPolicy::PseudoLRUPolicy(int64 num_sets, int64 assoc) - : AbstractReplacementPolicy(num_sets, assoc) -{ - // associativity cannot exceed capacity of tree representation - assert(num_sets > 0 && assoc > 1 && assoc <= sizeof(uint64)*4); - - m_trees = NULL; - m_num_levels = 0; - - m_effective_assoc = 1; - while (m_effective_assoc < assoc) { - // effective associativity is ceiling power of 2 - m_effective_assoc <<= 1; - } - assoc = m_effective_assoc; - while (true) { - assoc /= 2; - if(!assoc) break; - m_num_levels++; - } - assert(m_num_levels < sizeof(unsigned int)*4); - m_trees = new uint64[m_num_sets]; - for (unsigned i = 0; i < m_num_sets; i++) { - m_trees[i] = 0; - } -} - -inline -PseudoLRUPolicy::~PseudoLRUPolicy() -{ - if (m_trees != NULL) - delete[] m_trees; -} - -inline void -PseudoLRUPolicy::touch(int64 set, int64 index, Tick time) -{ - assert(index >= 0 && index < m_assoc); - assert(set >= 0 && set < m_num_sets); - - int tree_index = 0; - int node_val; - for (int i = m_num_levels - 1; i >= 0; i--) { - node_val = (index >> i)&1; - if (node_val) - m_trees[set] |= node_val << tree_index; - else - m_trees[set] &= ~(1 << tree_index); - tree_index = node_val ? (tree_index*2)+2 : (tree_index*2)+1; - } - m_last_ref_ptr[set][index] = time; -} - -inline int64 -PseudoLRUPolicy::getVictim(int64 set) const -{ - // assert(m_assoc != 0); - int64 index = 0; - - int tree_index = 0; - int node_val; - for (unsigned i = 0; i < m_num_levels; i++){ - node_val = (m_trees[set] >> tree_index) & 1; - index += node_val ? 0 : (m_effective_assoc >> (i + 1)); - tree_index = node_val ? (tree_index * 2) + 1 : (tree_index * 2) + 2; - } - assert(index >= 0 && index < m_effective_assoc); - - /* return either the found index or the max possible index */ - /* NOTE: this is not a fair replacement when assoc is not a power of 2 */ - return (index > (m_assoc - 1)) ? m_assoc - 1 : index; -} - #endif // __MEM_RUBY_STRUCTURES_PSEUDOLRUPOLICY_HH__ diff --git a/src/mem/ruby/structures/PseudoLRUReplacementPolicy.py b/src/mem/ruby/structures/PseudoLRUReplacementPolicy.py new file mode 100644 index 000000000..d922007f5 --- /dev/null +++ b/src/mem/ruby/structures/PseudoLRUReplacementPolicy.py @@ -0,0 +1,35 @@ +# +# Copyright (c) 2013 Advanced Micro Devices, Inc +# 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. +# +# Author: Derek Hower + +from ReplacementPolicy import ReplacementPolicy + +class PseudoLRUReplacementPolicy(ReplacementPolicy): + type = 'PseudoLRUReplacementPolicy' + cxx_class = 'PseudoLRUPolicy' + cxx_header = 'mem/ruby/structures/PseudoLRUPolicy.hh' diff --git a/src/mem/ruby/structures/ReplacementPolicy.py b/src/mem/ruby/structures/ReplacementPolicy.py new file mode 100644 index 000000000..4570cc9df --- /dev/null +++ b/src/mem/ruby/structures/ReplacementPolicy.py @@ -0,0 +1,43 @@ +# +# Copyright (c) 2013 Advanced Micro Devices, Inc +# 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. +# +# Author: Derek Hower + +from m5.params import * +from m5.proxy import * +from m5.SimObject import SimObject + +class ReplacementPolicy(SimObject): + type = 'ReplacementPolicy' + cxx_class = 'AbstractReplacementPolicy' + cxx_header = 'mem/ruby/structures/AbstractReplacementPolicy.hh' + + block_size = Param.Int(Parent.cache_line_size, "block size in bytes") + + size = Param.MemorySize(Parent.size, "capacity in bytes") + + assoc = Param.Int(Parent.assoc, "associativity") diff --git a/src/mem/ruby/structures/SConscript b/src/mem/ruby/structures/SConscript index ed00d7382..18ab9daed 100644 --- a/src/mem/ruby/structures/SConscript +++ b/src/mem/ruby/structures/SConscript @@ -35,12 +35,18 @@ if env['PROTOCOL'] == 'None': SimObject('Cache.py') SimObject('DirectoryMemory.py') +SimObject('LRUReplacementPolicy.py') +SimObject('PseudoLRUReplacementPolicy.py') +SimObject('ReplacementPolicy.py') SimObject('RubyMemoryControl.py') SimObject('RubyPrefetcher.py') SimObject('WireBuffer.py') +Source('AbstractReplacementPolicy.cc') Source('DirectoryMemory.cc') Source('CacheMemory.cc') +Source('LRUPolicy.cc') +Source('PseudoLRUPolicy.cc') Source('WireBuffer.cc') Source('RubyMemoryControl.cc') Source('MemoryNode.cc')