diff options
Diffstat (limited to 'src/mem/ruby/system')
-rw-r--r-- | src/mem/ruby/system/WeightedLRUPolicy.cc | 115 | ||||
-rw-r--r-- | src/mem/ruby/system/WeightedLRUPolicy.hh | 69 | ||||
-rw-r--r-- | src/mem/ruby/system/WeightedLRUReplacementPolicy.py | 5 |
3 files changed, 126 insertions, 63 deletions
diff --git a/src/mem/ruby/system/WeightedLRUPolicy.cc b/src/mem/ruby/system/WeightedLRUPolicy.cc index 2899f73a7..8f330d917 100644 --- a/src/mem/ruby/system/WeightedLRUPolicy.cc +++ b/src/mem/ruby/system/WeightedLRUPolicy.cc @@ -35,16 +35,12 @@ #include "mem/ruby/system/WeightedLRUPolicy.hh" +#include <cassert> +#include <memory> + WeightedLRUPolicy::WeightedLRUPolicy(const Params* p) - : AbstractReplacementPolicy(p), m_cache(p->cache) + : BaseReplacementPolicy(p) { - m_last_occ_ptr = new int*[m_num_sets]; - for (unsigned i = 0; i < m_num_sets; i++){ - m_last_occ_ptr[i] = new int[m_assoc]; - for (unsigned j = 0; j < m_assoc; j++){ - m_last_occ_ptr[i][j] = 0; - } - } } WeightedLRUPolicy * @@ -53,61 +49,78 @@ WeightedLRUReplacementPolicyParams::create() return new WeightedLRUPolicy(this); } -WeightedLRUPolicy::~WeightedLRUPolicy() -{ - if (m_last_occ_ptr != NULL){ - for (unsigned i = 0; i < m_num_sets; i++){ - if (m_last_occ_ptr[i] != NULL){ - delete[] m_last_occ_ptr[i]; - } - } - delete[] m_last_occ_ptr; - } -} - void -WeightedLRUPolicy::touch(int64_t set, int64_t index, Tick time) +WeightedLRUPolicy::touch(const std::shared_ptr<ReplacementData>& + replacement_data) const { - assert(index >= 0 && index < m_assoc); - assert(set >= 0 && set < m_num_sets); - - m_last_ref_ptr[set][index] = time; + std::static_pointer_cast<WeightedLRUReplData>(replacement_data)-> + last_touch_tick = curTick(); } void -WeightedLRUPolicy::touch(int64_t set, int64_t index, Tick time, int occupancy) +WeightedLRUPolicy::touch(const std::shared_ptr<ReplacementData>& + replacement_data, int occupancy) const { - assert(index >= 0 && index < m_assoc); - assert(set >= 0 && set < m_num_sets); - - m_last_ref_ptr[set][index] = time; - m_last_occ_ptr[set][index] = occupancy; + std::static_pointer_cast<WeightedLRUReplData>(replacement_data)-> + last_touch_tick = curTick(); + std::static_pointer_cast<WeightedLRUReplData>(replacement_data)-> + last_occ_ptr = occupancy; } -int64_t -WeightedLRUPolicy::getVictim(int64_t set) const +ReplaceableEntry* +WeightedLRUPolicy::getVictim(const ReplacementCandidates& candidates) const { - Tick time, smallest_time; - int64_t smallest_index; - - smallest_index = 0; - smallest_time = m_last_ref_ptr[set][0]; - int smallest_weight = m_last_occ_ptr[set][0]; + assert(candidates.size() > 0); - for (unsigned i = 1; i < m_assoc; i++) { + ReplaceableEntry* victim = candidates[0]; + // Use weight (last_occ_ptr) to find victim. + // Evict the block that has the smallest weight. + // If two blocks have the same weight, evict the oldest one. + for (const auto& candidate : candidates) { + // candidate's replacement_data + std::shared_ptr<WeightedLRUReplData> candidate_replacement_data = + std::static_pointer_cast<WeightedLRUReplData>( + candidate->replacementData); + // victim's replacement_data + std::shared_ptr<WeightedLRUReplData> victim_replacement_data = + std::static_pointer_cast<WeightedLRUReplData>( + victim->replacementData); - int weight = m_last_occ_ptr[set][i]; - if (weight < smallest_weight) { - smallest_weight = weight; - smallest_index = i; - smallest_time = m_last_ref_ptr[set][i]; - } else if (weight == smallest_weight) { - time = m_last_ref_ptr[set][i]; - if (time < smallest_time) { - smallest_index = i; - smallest_time = time; + if (candidate_replacement_data->last_occ_ptr < + victim_replacement_data->last_occ_ptr) { + victim = candidate; + } else if (candidate_replacement_data->last_occ_ptr == + victim_replacement_data->last_occ_ptr) { + // Evict the block with a smaller tick. + Tick time = candidate_replacement_data->last_touch_tick; + if (time < victim_replacement_data->last_touch_tick) { + victim = candidate; } } } - return smallest_index; + return victim; +} + +std::shared_ptr<ReplacementData> +WeightedLRUPolicy::instantiateEntry() +{ + return std::shared_ptr<ReplacementData>(new WeightedLRUReplData); +} + +void +WeightedLRUPolicy::reset(const std::shared_ptr<ReplacementData>& + replacement_data) const +{ + // Set last touch timestamp + std::static_pointer_cast<WeightedLRUReplData>( + replacement_data)->last_touch_tick = curTick(); +} + +void +WeightedLRUPolicy::invalidate(const std::shared_ptr<ReplacementData>& + replacement_data) const +{ + // Reset last touch timestamp + std::static_pointer_cast<WeightedLRUReplData>( + replacement_data)->last_touch_tick = Tick(0); } diff --git a/src/mem/ruby/system/WeightedLRUPolicy.hh b/src/mem/ruby/system/WeightedLRUPolicy.hh index 47fcec4a6..a11784584 100644 --- a/src/mem/ruby/system/WeightedLRUPolicy.hh +++ b/src/mem/ruby/system/WeightedLRUPolicy.hh @@ -36,27 +36,78 @@ #ifndef __MEM_RUBY_SYSTEM_WEIGHTEDLRUPOLICY_HH__ #define __MEM_RUBY_SYSTEM_WEIGHTEDLRUPOLICY_HH__ -#include "mem/ruby/structures/AbstractReplacementPolicy.hh" +#include "mem/cache/replacement_policies/base.hh" #include "mem/ruby/structures/CacheMemory.hh" #include "params/WeightedLRUReplacementPolicy.hh" /* Simple true LRU replacement policy */ -class WeightedLRUPolicy : public AbstractReplacementPolicy +class WeightedLRUPolicy : public BaseReplacementPolicy { + protected: + /** Weighted LRU implementation of replacement data. */ + struct WeightedLRUReplData : ReplacementData + { + /** pointer for last occupancy */ + int last_occ_ptr; + + /** Tick on which the entry was last touched. */ + Tick last_touch_tick; + + /** + * Default constructor. Invalidate data. + */ + WeightedLRUReplData() : ReplacementData(), + last_occ_ptr(0), last_touch_tick(0) {} + }; public: typedef WeightedLRUReplacementPolicyParams Params; WeightedLRUPolicy(const Params* p); - ~WeightedLRUPolicy(); + ~WeightedLRUPolicy() {} + + /** + * Invalidate replacement data to set it as the next probable victim. + * Sets its last touch tick as the starting tick. + * + * @param replacement_data Replacement data to be invalidated. + */ + void invalidate(const std::shared_ptr<ReplacementData>& replacement_data) + const override; + /** + * Touch an entry to update its replacement data. + * Sets its last touch tick as the current tick. + * + * @param replacement_data Replacement data to be touched. + */ + void touch(const std::shared_ptr<ReplacementData>& + replacement_data) const override; + void touch(const std::shared_ptr<ReplacementData>& replacement_data, + int occupancy) const; - void touch(int64_t set, int64_t way, Tick time) override; - void touch(int64_t set, int64_t way, Tick time, int occupancy); - int64_t getVictim(int64_t set) const override; + /** + * Reset replacement data. Used when an entry is inserted. + * Sets its last touch tick as the current tick. + * + * @param replacement_data Replacement data to be reset. + */ + void reset(const std::shared_ptr<ReplacementData>& replacement_data) const + override; - bool useOccupancy() const override { return true; } + /** + * Instantiate a replacement data entry. + * + * @return A shared pointer to the new replacement data. + */ + std::shared_ptr<ReplacementData> instantiateEntry() override; - CacheMemory * m_cache; - int **m_last_occ_ptr; + /** + * Find replacement victim using weight. + * + * @param candidates Replacement candidates, selected by indexing policy. + * @return Replacement entry to be replaced. + */ + ReplaceableEntry* getVictim(const ReplacementCandidates& + candidates) const override; }; #endif // __MEM_RUBY_SYSTEM_WeightedLRUPolicy_HH__ diff --git a/src/mem/ruby/system/WeightedLRUReplacementPolicy.py b/src/mem/ruby/system/WeightedLRUReplacementPolicy.py index fa50c95dc..48143e5d9 100644 --- a/src/mem/ruby/system/WeightedLRUReplacementPolicy.py +++ b/src/mem/ruby/system/WeightedLRUReplacementPolicy.py @@ -33,10 +33,9 @@ from m5.params import * from m5.proxy import * -from m5.objects.ReplacementPolicy import ReplacementPolicy +from m5.objects.ReplacementPolicies import BaseReplacementPolicy -class WeightedLRUReplacementPolicy(ReplacementPolicy): +class WeightedLRUReplacementPolicy(BaseReplacementPolicy): type = "WeightedLRUReplacementPolicy" cxx_class = "WeightedLRUPolicy" cxx_header = "mem/ruby/system/WeightedLRUPolicy.hh" - cache = Param.RubyCache("") |