From d7aded6fbfaa1fa1f31996c02b16ad4c4bb9ec9e Mon Sep 17 00:00:00 2001 From: brsf11 Date: Sun, 23 Jun 2024 20:34:37 -0700 Subject: [PATCH 1/2] Machine: Not Most Recently Used cache policy --- src/machine/machineconfig.h | 3 ++- src/machine/memory/cache/cache.test.cpp | 6 ++--- src/machine/memory/cache/cache_policy.cpp | 27 +++++++++++++++++++++++ src/machine/memory/cache/cache_policy.h | 26 ++++++++++++++++++++++ 4 files changed, 58 insertions(+), 4 deletions(-) diff --git a/src/machine/machineconfig.h b/src/machine/machineconfig.h index 01b27485..0e45f067 100644 --- a/src/machine/machineconfig.h +++ b/src/machine/machineconfig.h @@ -45,7 +45,8 @@ class CacheConfig { RP_RAND, // Random RP_LRU, // Least recently used RP_LFU, // Least frequently used - RP_PLRU // Pseudo Least recently used + RP_PLRU, // Pseudo Least recently used + RP_NMRU // Not most recently used }; enum WritePolicy { diff --git a/src/machine/memory/cache/cache.test.cpp b/src/machine/memory/cache/cache.test.cpp index 889e1b19..9f9ce042 100644 --- a/src/machine/memory/cache/cache.test.cpp +++ b/src/machine/memory/cache/cache.test.cpp @@ -34,8 +34,8 @@ constexpr array values { 0x4142434445464748 }; * Cache configuration parameters for testing * (all combinations are tested) */ -constexpr array replacement_policies { - CacheConfig::RP_RAND, CacheConfig::RP_LFU, CacheConfig::RP_LRU, CacheConfig::RP_PLRU +constexpr array replacement_policies { + CacheConfig::RP_RAND, CacheConfig::RP_LFU, CacheConfig::RP_LRU, CacheConfig::RP_PLRU, CacheConfig::RP_NMRU }; constexpr array write_policies { CacheConfig::WP_THROUGH_NOALLOC, // THIS @@ -242,7 +242,7 @@ void TestCache::cache_correctness() { // stderr, "{ %d, %d }, ", cache.get_hit_count(), // cache.get_miss_count()); - if (cache_config.replacement_policy() != CacheConfig::RP_RAND) { + if ((cache_config.replacement_policy() != CacheConfig::RP_RAND) && (cache_config.replacement_policy() != CacheConfig::RP_NMRU)) { // Performance of random policy is implementation dependant and // meaningless. QCOMPARE(performance, cache_test_performance_data.at(case_number)); diff --git a/src/machine/memory/cache/cache_policy.cpp b/src/machine/memory/cache/cache_policy.cpp index 7875828e..15a4e35a 100644 --- a/src/machine/memory/cache/cache_policy.cpp +++ b/src/machine/memory/cache/cache_policy.cpp @@ -22,6 +22,8 @@ CachePolicy::get_policy_instance(const CacheConfig *config) { config->associativity(), config->set_count()); case CacheConfig::RP_PLRU: return std::make_unique(config->associativity(), config->set_count()); + case CacheConfig::RP_NMRU: + return std::make_unique(config->associativity(), config->set_count()); } } else { // Disabled cache will never use it. @@ -172,4 +174,29 @@ size_t CachePolicyPLRU::select_way_to_evict(size_t row) const { } return (idx >= associativity) ? (associativity - 1) : idx; } + +CachePolicyNMRU::CachePolicyNMRU(size_t associativity, size_t set_count) + : associativity(associativity) { + mru_ptr.resize(set_count); + for (auto &row : mru_ptr) { + row = 0; // Initially point to block 0 + } + std::srand(1); // NOLINT(cert-msc51-cpp) +} + +void CachePolicyNMRU::update_stats(size_t way, size_t row, bool is_valid) { + UNUSED(is_valid) + auto &row_ptr = mru_ptr.at(row); // Set currently accessed block to most recently used + row_ptr = way; +} + +size_t CachePolicyNMRU::select_way_to_evict(size_t row) const { + if(associativity == 1) { + return 0; + } + uint32_t idx = std::rand() % (associativity - 1); + auto &row_ptr = mru_ptr.at(row); + idx = (idx < row_ptr) ? idx : idx + 1; + return idx; +} } // namespace machine diff --git a/src/machine/memory/cache/cache_policy.h b/src/machine/memory/cache/cache_policy.h index b9bf12d6..708fa928 100644 --- a/src/machine/memory/cache/cache_policy.h +++ b/src/machine/memory/cache/cache_policy.h @@ -129,6 +129,32 @@ class CachePolicyPLRU final : public CachePolicy { const size_t associativityCLog2; }; +/** + * Not Most Recently Used + * + * Select Randomly from Not Most + * Recently Used Blocks + */ +class CachePolicyNMRU final : public CachePolicy { +public: + /** + * @param associativity degree of assiciaivity + * @param set_count number of blocks / rows in a way (or sets in + * cache) + */ + CachePolicyNMRU(size_t associativity, size_t set_count); + + [[nodiscard]] size_t select_way_to_evict(size_t row) const final; + + void update_stats(size_t way, size_t row, bool is_valid) final; + +private: + /** + * Pointer to Most Recently Used Block + */ + std::vector mru_ptr; + const size_t associativity; +}; } // namespace machine #endif // CACHE_POLICY_H From 65528cdabfaf15c89a42182d552fe1b51d47513c Mon Sep 17 00:00:00 2001 From: brsf11 Date: Sun, 23 Jun 2024 20:35:23 -0700 Subject: [PATCH 2/2] GUI: Not Most Recently Used cache policy --- src/gui/dialogs/new/NewDialogCache.ui | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/dialogs/new/NewDialogCache.ui b/src/gui/dialogs/new/NewDialogCache.ui index 52f1586e..fb74b4f0 100644 --- a/src/gui/dialogs/new/NewDialogCache.ui +++ b/src/gui/dialogs/new/NewDialogCache.ui @@ -97,6 +97,11 @@ Pseudo Least Recently Used (PLRU) + + + Not Most Recently Used (NMRU) + +