From 70686e22dafbfe94f5954a1767310c38eddedf51 Mon Sep 17 00:00:00 2001 From: Wei Song Date: Mon, 25 Nov 2024 14:01:31 +0800 Subject: [PATCH 1/7] fix prefetch accoridng to Guo2022-MICRO --- cache/coherence.hpp | 89 +++++++++++++-------------------------------- cache/exclusive.hpp | 10 +++-- cache/mirage.hpp | 19 ++-------- 3 files changed, 35 insertions(+), 83 deletions(-) diff --git a/cache/coherence.hpp b/cache/coherence.hpp index 84c83ac..7fd5d6e 100644 --- a/cache/coherence.hpp +++ b/cache/coherence.hpp @@ -47,7 +47,6 @@ class OuterCohPortBase virtual void acquire_req(uint64_t addr, CMMetadataBase *meta, CMDataBase *data, coh_cmd_t cmd, uint64_t *delay) = 0; virtual void writeback_req(uint64_t addr, CMMetadataBase *meta, CMDataBase *data, coh_cmd_t cmd, uint64_t *delay) = 0; - virtual void prefetch_req(uint64_t addr, coh_cmd_t cmd, uint64_t *delay) = 0; // may not implement probe_resp() and finish_req() if the port is uncached virtual std::pair probe_resp(uint64_t addr, CMMetadataBase *meta, CMDataBase *data, coh_cmd_t cmd, uint64_t *delay) { return std::make_pair(false,false); } @@ -78,7 +77,6 @@ class InnerCohPortBase virtual void acquire_resp(uint64_t addr, CMDataBase *data_inner, CMMetadataBase *meta_inner, coh_cmd_t outer_cmd, uint64_t *delay) = 0; virtual void writeback_resp(uint64_t addr, CMDataBase *data_inner, CMMetadataBase *meta_inner, coh_cmd_t outer_cmd, uint64_t *delay) = 0; - virtual void prefetch_resp(uint64_t addr, coh_cmd_t outer_cmd, uint64_t *delay) = 0; // may not implement probe_req() and finish_resp() if the port is uncached virtual std::pair probe_req(uint64_t addr, CMMetadataBase *meta, CMDataBase *data, coh_cmd_t cmd, uint64_t *delay) { return std::make_pair(false,false); } @@ -144,11 +142,6 @@ class OuterCohPortUncached : public OuterCohPortBase Policy::meta_after_writeback(outer_cmd, meta); } - virtual void prefetch_req(uint64_t addr, coh_cmd_t outer_cmd, uint64_t *delay) override { - outer_cmd.id = coh_id; - coh->prefetch_resp(addr, outer_cmd, delay); - } - virtual void query_loc_req(uint64_t addr, std::list *locs) override { coh->query_loc_resp(addr, locs); } @@ -225,10 +218,11 @@ class InnerCohPortUncached : public InnerCohPortBase public: virtual void acquire_resp(uint64_t addr, CMDataBase *data_inner, CMMetadataBase *meta_inner, coh_cmd_t cmd, uint64_t *delay) override { auto [meta, data, ai, s, w, hit] = access_line(addr, cmd, XactPrio::acquire, delay); + bool act_as_prefetch = coh::is_prefetch(cmd) && Policy::is_uncached(); // only tweak replace priority at the LLC accoridng to [Guo2022-MICRO] if (data_inner && data) data_inner->copy(data); Policy::meta_after_grant(cmd, meta, meta_inner); - cache->hook_read(addr, ai, s, w, hit, coh::is_prefetch(cmd), meta, data, delay); + cache->hook_read(addr, ai, s, w, hit, act_as_prefetch, meta, data, delay); finish_record(addr, coh::cmd_for_finish(cmd.id), !hit, meta, ai, s); if(cmd.id == -1) finish_resp(addr, coh::cmd_for_finish(cmd.id)); } @@ -240,10 +234,6 @@ class InnerCohPortUncached : public InnerCohPortBase write_line(addr, data_inner, meta_inner, cmd, delay); } - virtual void prefetch_resp(uint64_t addr, coh_cmd_t cmd, uint64_t *delay) override { - prefetch_line(addr, cmd, delay); - } - virtual void query_loc_resp(uint64_t addr, std::list *locs) override { outer->query_loc_req(addr, locs); locs->push_front(cache->query_loc(addr)); @@ -268,23 +258,21 @@ class InnerCohPortUncached : public InnerCohPortBase } virtual std::tuple - check_hit_or_replace(uint64_t addr, uint16_t prio, bool do_replace, bool prefetch, uint64_t *delay) { // check hit or get a replacement target + check_hit_or_replace(uint64_t addr, uint16_t prio, bool do_replace, uint64_t *delay) { // check hit or get a replacement target uint32_t ai, s, w; CMMetadataBase *meta = nullptr; CMDataBase *data = nullptr; bool hit; if constexpr (EnMT) { while(true) { - hit = cache->hit(addr, &ai, &s, &w, prio, !prefetch); + hit = cache->hit(addr, &ai, &s, &w, prio, true); if(hit) { std::tie(meta, data) = cache->access_line(ai, s, w); - if(!prefetch) { // no need to lock for prefetch - meta->lock(); - if(!cache->check_mt_state(ai, s, prio) || !meta->match(addr)) { // acquire is intercepted by a probe and even invalidated - meta->unlock(); meta = nullptr; data = nullptr; - cache->reset_mt_state(ai, s, prio); - continue; // redo the hit check - } + meta->lock(); + if(!cache->check_mt_state(ai, s, prio) || !meta->match(addr)) { // acquire is intercepted by a probe and even invalidated + meta->unlock(); meta = nullptr; data = nullptr; + cache->reset_mt_state(ai, s, prio); + continue; // redo the hit check } } else if(do_replace) { // miss if(cache->replace(addr, &ai, &s, &w, prio)) { // lock the cache set and get a replacement candidate @@ -310,8 +298,7 @@ class InnerCohPortUncached : public InnerCohPortBase virtual std::tuple access_line(uint64_t addr, coh_cmd_t cmd, uint16_t prio, uint64_t *delay) { // common function for access a line in the cache - auto [hit, meta, data, ai, s, w] = check_hit_or_replace(addr, prio, true, false, delay); - + auto [hit, meta, data, ai, s, w] = check_hit_or_replace(addr, prio, true, delay); if(hit) { auto sync = Policy::access_need_sync(cmd, meta); if(sync.first) { @@ -325,7 +312,7 @@ class InnerCohPortUncached : public InnerCohPortBase else if(promote_local) meta->to_modified(-1); } else { // miss if(meta->is_valid()) evict(meta, data, ai, s, w, delay); - outer->acquire_req(addr, meta, data, Policy::cmd_for_outer_acquire(cmd), delay); // fetch the missing block + outer->acquire_req(addr, meta, data, coh::is_prefetch(cmd) ? cmd : Policy::cmd_for_outer_acquire(cmd), delay); // fetch the missing block } return std::make_tuple(meta, data, ai, s, w, hit); } @@ -344,7 +331,7 @@ class InnerCohPortUncached : public InnerCohPortBase if constexpr (!Policy::is_uncached()) outer->writeback_req(addr, nullptr, nullptr, coh::cmd_for_flush(), delay); else { - auto [hit, meta, data, ai, s, w] = check_hit_or_replace(addr, XactPrio::flush, false, false, delay); + auto [hit, meta, data, ai, s, w] = check_hit_or_replace(addr, XactPrio::flush, false, delay); auto [probe, probe_cmd] = Policy::flush_need_sync(cmd, meta); if(!hit) return; @@ -365,20 +352,6 @@ class InnerCohPortUncached : public InnerCohPortBase } } - virtual void prefetch_line(uint64_t addr, coh_cmd_t cmd, uint64_t *delay) { - if constexpr (!Policy::is_uncached()) - outer->prefetch_req(addr, coh::cmd_for_prefetch(), delay); - else { - auto [hit, meta, data, ai, s, w] = check_hit_or_replace(addr, XactPrio::acquire, true, true, delay); - if(!hit) { - if(meta->is_valid()) evict(meta, data, ai, s, w, delay); - outer->acquire_req(addr, meta, data, coh::cmd_for_prefetch(), delay); // fetch the missing block - cache->hook_read(addr, ai, s, w, hit, true, meta, data, delay); - finish_record(addr, coh::cmd_for_finish(-1), !hit, meta, ai, s); - finish_resp(addr, coh::cmd_for_finish(-1)); - } - } - } }; template