From eebd4787bf3450baaa10b8c8b68d455b1f3fffa5 Mon Sep 17 00:00:00 2001 From: wangzd12138 Date: Tue, 4 Jun 2024 11:04:06 +0800 Subject: [PATCH 1/6] Add finish port. --- cache/coh_policy.hpp | 2 ++ cache/coherence.hpp | 28 +++++++++++++++++++++++++--- cache/mi.hpp | 7 +++++++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/cache/coh_policy.hpp b/cache/coh_policy.hpp index e29ee1f..96e6dd3 100644 --- a/cache/coh_policy.hpp +++ b/cache/coh_policy.hpp @@ -173,6 +173,8 @@ class CohPolicyBase { return std::make_pair(false, cmd_for_null()); } + // finish + virtual bool finish_need_req() const = 0; }; #endif diff --git a/cache/coherence.hpp b/cache/coherence.hpp index 0803a31..a326dac 100644 --- a/cache/coherence.hpp +++ b/cache/coherence.hpp @@ -43,6 +43,9 @@ class OuterCohPortBase bool is_uncached() const { return coh_id == -1; } virtual void query_loc_req(uint64_t addr, std::list *locs) = 0; + + virtual void finish_req(uint64_t addr) = 0; + friend CoherentCacheBase; // deferred assignment for cache }; @@ -73,6 +76,8 @@ class InnerCohPortBase 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); } // may not implement if not supported virtual void query_loc_resp(uint64_t addr, std::list *locs) = 0; + + virtual void finish_resp(uint64_t addr) {}; friend CoherentCacheBase; // deferred assignment for cache }; @@ -100,6 +105,9 @@ class OuterCohPortUncached : public OuterCohPortBase virtual void query_loc_req(uint64_t addr, std::list *locs){ coh->query_loc_resp(addr, locs); } + virtual void finish_req(uint64_t addr){ + coh->finish_resp(addr); + } }; // common behavior for cached outer ports @@ -264,6 +272,8 @@ class InnerCohPortT : public IPUC { protected: using IPUC::coh; + using IPUC::outer; + using IPUC::policy; public: InnerCohPortT(policy_ptr policy) : IPUC(policy) {} virtual ~InnerCohPortT() {} @@ -280,6 +290,11 @@ class InnerCohPortT : public IPUC } return std::make_pair(hit, writeback); } + virtual void finish_resp(uint64_t addr){ + if(policy->finish_need_req()) { + outer->finish_req(addr); + } + } }; typedef InnerCohPortT InnerCohPort; @@ -317,6 +332,7 @@ class CoreInterface : public InnerCohPortUncached, public CoreInterfaceBase { auto cmd = policy->cmd_for_read(); auto [meta, data, ai, s, w, hit] = access_line(addr, cmd, delay); cache->hook_read(addr, ai, s, w, hit, meta, data, delay); + outer->finish_req(addr); return data; } @@ -327,11 +343,12 @@ class CoreInterface : public InnerCohPortUncached, public CoreInterfaceBase { meta->to_dirty(); if(data) data->copy(m_data); cache->hook_write(addr, ai, s, w, hit, false, meta, data, delay); + outer->finish_req(addr); } - virtual void flush(uint64_t addr, uint64_t *delay) { addr = normalize(addr); flush_line(addr, policy->cmd_for_flush(), delay); } + virtual void flush(uint64_t addr, uint64_t *delay) { addr = normalize(addr); flush_line(addr, policy->cmd_for_flush(), delay); outer->finish_req(addr);} - virtual void writeback(uint64_t addr, uint64_t *delay) { addr = normalize(addr); flush_line(addr, policy->cmd_for_writeback(), delay); } + virtual void writeback(uint64_t addr, uint64_t *delay) { addr = normalize(addr); flush_line(addr, policy->cmd_for_writeback(), delay); outer->finish_req(addr);} virtual void writeback_invalidate(uint64_t *delay) { assert(nullptr == "Error: L1.writeback_invalidate() is not implemented yet!"); @@ -343,8 +360,10 @@ class CoreInterface : public InnerCohPortUncached, public CoreInterfaceBase { for(int iset=0; iset < nset; iset++) for(int iway=0; iway < nway; iway++) { auto [meta, data] = cache->access_line(ipar, iset, iway); - if(meta->is_valid()) + if(meta->is_valid()){ flush_line(meta->addr(iset), policy->cmd_for_flush(), delay); + outer->finish_req(meta->addr(iset)); + } } } @@ -436,6 +455,9 @@ class SliceDispatcher : public CohMasterBase virtual void query_loc_resp(uint64_t addr, std::list *locs){ cohm[hasher(addr)]->query_loc_resp(addr, locs); } + virtual void finish_resp(uint64_t addr){ + cohm[hasher(addr)]->finish_resp(addr); + } }; #endif diff --git a/cache/mi.hpp b/cache/mi.hpp index c9ac632..49db417 100644 --- a/cache/mi.hpp +++ b/cache/mi.hpp @@ -83,6 +83,13 @@ class MIPolicy : public CohPolicyBase return std::make_tuple(false, false, cmd_for_null()); } + virtual bool finish_need_req() const { + if constexpr (isLLC) { + return false; + } else { + return true; + } + } }; #endif From 313c2a8cbcfdfc56802eff1e07ec8c76f19790c1 Mon Sep 17 00:00:00 2001 From: Wei Song Date: Wed, 5 Jun 2024 11:36:48 +0800 Subject: [PATCH 2/6] simplify the support of finish --- cache/coh_policy.hpp | 2 -- cache/coherence.hpp | 37 ++++++++++++++++++------------------- cache/mi.hpp | 7 ------- 3 files changed, 18 insertions(+), 28 deletions(-) diff --git a/cache/coh_policy.hpp b/cache/coh_policy.hpp index 96e6dd3..e29ee1f 100644 --- a/cache/coh_policy.hpp +++ b/cache/coh_policy.hpp @@ -173,8 +173,6 @@ class CohPolicyBase { return std::make_pair(false, cmd_for_null()); } - // finish - virtual bool finish_need_req() const = 0; }; #endif diff --git a/cache/coherence.hpp b/cache/coherence.hpp index a326dac..471fe57 100644 --- a/cache/coherence.hpp +++ b/cache/coherence.hpp @@ -39,13 +39,13 @@ 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 std::pair probe_resp(uint64_t addr, CMMetadataBase *meta, CMDataBase *data, coh_cmd_t cmd, uint64_t *delay) { return std::make_pair(false,false); } // may not implement if not supported + + // 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); } + virtual void finish_req(uint64_t addr) {} bool is_uncached() const { return coh_id == -1; } virtual void query_loc_req(uint64_t addr, std::list *locs) = 0; - - virtual void finish_req(uint64_t addr) = 0; - friend CoherentCacheBase; // deferred assignment for cache }; @@ -73,11 +73,12 @@ 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 cmd, uint64_t *delay) = 0; - 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); } // may not implement if not supported - - virtual void query_loc_resp(uint64_t addr, std::list *locs) = 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); } virtual void finish_resp(uint64_t addr) {}; + + virtual void query_loc_resp(uint64_t addr, std::list *locs) = 0; friend CoherentCacheBase; // deferred assignment for cache }; @@ -105,9 +106,6 @@ class OuterCohPortUncached : public OuterCohPortBase virtual void query_loc_req(uint64_t addr, std::list *locs){ coh->query_loc_resp(addr, locs); } - virtual void finish_req(uint64_t addr){ - coh->finish_resp(addr); - } }; // common behavior for cached outer ports @@ -148,6 +146,11 @@ class OuterCohPortT : public OPUC cache->hook_manage(addr, ai, s, w, hit, OPUC::policy->is_outer_evict(outer_cmd), writeback, meta, data, delay); return std::make_pair(hit, writeback); } + + virtual void finish_req(uint64_t addr){ + assert(!OPUC::is_uncached()); + OPUC::coh->finish_resp(addr); + } }; typedef OuterCohPortT OuterCohPort; @@ -273,7 +276,6 @@ class InnerCohPortT : public IPUC protected: using IPUC::coh; using IPUC::outer; - using IPUC::policy; public: InnerCohPortT(policy_ptr policy) : IPUC(policy) {} virtual ~InnerCohPortT() {} @@ -290,10 +292,9 @@ class InnerCohPortT : public IPUC } return std::make_pair(hit, writeback); } + virtual void finish_resp(uint64_t addr){ - if(policy->finish_need_req()) { - outer->finish_req(addr); - } + outer->finish_req(addr); } }; @@ -346,9 +347,9 @@ class CoreInterface : public InnerCohPortUncached, public CoreInterfaceBase { outer->finish_req(addr); } - virtual void flush(uint64_t addr, uint64_t *delay) { addr = normalize(addr); flush_line(addr, policy->cmd_for_flush(), delay); outer->finish_req(addr);} + virtual void flush(uint64_t addr, uint64_t *delay) { addr = normalize(addr); flush_line(addr, policy->cmd_for_flush(), delay); } - virtual void writeback(uint64_t addr, uint64_t *delay) { addr = normalize(addr); flush_line(addr, policy->cmd_for_writeback(), delay); outer->finish_req(addr);} + virtual void writeback(uint64_t addr, uint64_t *delay) { addr = normalize(addr); flush_line(addr, policy->cmd_for_writeback(), delay); } virtual void writeback_invalidate(uint64_t *delay) { assert(nullptr == "Error: L1.writeback_invalidate() is not implemented yet!"); @@ -360,10 +361,8 @@ class CoreInterface : public InnerCohPortUncached, public CoreInterfaceBase { for(int iset=0; iset < nset; iset++) for(int iway=0; iway < nway; iway++) { auto [meta, data] = cache->access_line(ipar, iset, iway); - if(meta->is_valid()){ + if(meta->is_valid()) flush_line(meta->addr(iset), policy->cmd_for_flush(), delay); - outer->finish_req(meta->addr(iset)); - } } } diff --git a/cache/mi.hpp b/cache/mi.hpp index 49db417..c9ac632 100644 --- a/cache/mi.hpp +++ b/cache/mi.hpp @@ -83,13 +83,6 @@ class MIPolicy : public CohPolicyBase return std::make_tuple(false, false, cmd_for_null()); } - virtual bool finish_need_req() const { - if constexpr (isLLC) { - return false; - } else { - return true; - } - } }; #endif From be99729f0aa4dc9ec71719ff0308596c11a4dde2 Mon Sep 17 00:00:00 2001 From: wangzd12138 Date: Thu, 6 Jun 2024 10:20:18 +0800 Subject: [PATCH 3/6] lower cache sends finish instead of upper uncached --- cache/coherence.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/cache/coherence.hpp b/cache/coherence.hpp index 471fe57..fd28713 100644 --- a/cache/coherence.hpp +++ b/cache/coherence.hpp @@ -167,6 +167,7 @@ class InnerCohPortUncached : public InnerCohPortBase if (data_inner && data) data_inner->copy(data); policy->meta_after_grant(cmd, meta, meta_inner); cache->hook_read(addr, ai, s, w, hit, meta, data, delay); + if(cmd.id == -1) finish_resp(addr); } virtual void writeback_resp(uint64_t addr, CMDataBase *data_inner, CMMetadataBase *meta_inner, coh_cmd_t cmd, uint64_t *delay) { From afc1931e012da6425beb1710c2c702453cfce7df Mon Sep 17 00:00:00 2001 From: wangzd12138 Date: Thu, 6 Jun 2024 10:24:24 +0800 Subject: [PATCH 4/6] modify exclusive to simply support finish port --- cache/exclusive.hpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cache/exclusive.hpp b/cache/exclusive.hpp index 6a43e31..66454df 100644 --- a/cache/exclusive.hpp +++ b/cache/exclusive.hpp @@ -200,6 +200,7 @@ class ExclusiveInnerCohPortUncachedBroadcast : public InnerCohPortUncached if (data_inner && data) data_inner->copy(data); policy->meta_after_grant(cmd, meta, meta_inner); cache->hook_read(addr, ai, s, w, hit, meta, data, delay); + if(cmd.id == -1) finish_resp(addr); cache->meta_return_buffer(meta); cache->data_return_buffer(data); @@ -362,6 +363,7 @@ class ExclusiveInnerCohPortUncachedDirectory : public InnerCohPortUncached if (data_inner && data) data_inner->copy(data); policy->meta_after_grant(outer_cmd, meta, meta_inner); cache->hook_read(addr, ai, s, w, hit, meta, data, delay); + if(outer_cmd.id == -1) finish_resp(addr); // difficult to know when data is borrowed from buffer, just return it. cache->data_return_buffer(data); @@ -562,6 +564,11 @@ class ExclusiveOuterCohPortBroadcastT : public OPUC return std::make_pair(hit||probe_hit, writeback); } + virtual void finish_req(uint64_t addr){ + assert(!OPUC::is_uncached()); + OPUC::coh->finish_resp(addr); + } + }; typedef ExclusiveOuterCohPortBroadcastT ExclusiveOuterCohPortBroadcast; @@ -613,6 +620,11 @@ class ExclusiveOuterCohPortDirectoryT : public OPUC return std::make_pair(hit||probe_hit, writeback); } + virtual void finish_req(uint64_t addr){ + assert(!OPUC::is_uncached()); + OPUC::coh->finish_resp(addr); + } + }; typedef ExclusiveOuterCohPortDirectoryT ExclusiveOuterCohPortDirectory; From 78eae3dcffd87627bcb279255e0e840afc2b0277 Mon Sep 17 00:00:00 2001 From: Wei Song Date: Thu, 6 Jun 2024 15:58:13 +0800 Subject: [PATCH 5/6] do not unnecessarily forward finish --- cache/coh_policy.hpp | 3 +++ cache/coherence.hpp | 62 ++++++++++++++++++++++++++++++++------------ cache/exclusive.hpp | 24 ++++++----------- 3 files changed, 57 insertions(+), 32 deletions(-) diff --git a/cache/coh_policy.hpp b/cache/coh_policy.hpp index e29ee1f..22a7ce1 100644 --- a/cache/coh_policy.hpp +++ b/cache/coh_policy.hpp @@ -30,6 +30,7 @@ class CohPolicyBase { static const uint32_t release_msg = 2; static const uint32_t probe_msg = 3; static const uint32_t flush_msg = 4; + static const uint32_t finish_msg = 5; static const uint32_t fetch_read_act = 0; static const uint32_t fetch_write_act = 1; static const uint32_t evict_act = 2; @@ -48,6 +49,7 @@ class CohPolicyBase { bool is_release(coh_cmd_t cmd) const { return cmd.msg == release_msg; } bool is_probe(coh_cmd_t cmd) const { return cmd.msg == probe_msg; } bool is_flush(coh_cmd_t cmd) const { return cmd.msg == flush_msg; } + bool is_finish(coh_cmd_t cmd) const { return cmd.msg == finish_msg; } // action type bool is_fetch_read(coh_cmd_t cmd) const { return cmd.act == fetch_read_act; } @@ -73,6 +75,7 @@ class CohPolicyBase { coh_cmd_t cmd_for_probe_writeback(int32_t id) const { return {id, probe_msg, writeback_act }; } coh_cmd_t cmd_for_probe_release(int32_t id) const { return {id, probe_msg, evict_act }; } coh_cmd_t cmd_for_probe_downgrade(int32_t id) const { return {id, probe_msg, downgrade_act }; } + coh_cmd_t cmd_for_finish(int32_t id) const { return {id, finish_msg, 0 }; } virtual coh_cmd_t cmd_for_outer_acquire(coh_cmd_t cmd) const = 0; diff --git a/cache/coherence.hpp b/cache/coherence.hpp index fd28713..37bc612 100644 --- a/cache/coherence.hpp +++ b/cache/coherence.hpp @@ -72,11 +72,12 @@ 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 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; // 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); } - virtual void finish_resp(uint64_t addr) {}; + virtual void finish_record(uint64_t addr, coh_cmd_t outer_cmd) {}; + virtual void finish_resp(uint64_t addr, coh_cmd_t outer_cmd) {}; virtual void query_loc_resp(uint64_t addr, std::list *locs) = 0; @@ -108,8 +109,21 @@ class OuterCohPortUncached : public OuterCohPortBase } }; +// common behvior for cached outer ports +class OuterCohPortCachedBase : public OuterCohPortUncached +{ +public: + OuterCohPortCachedBase(policy_ptr policy) : OuterCohPortUncached(policy) {} + virtual ~OuterCohPortCachedBase() {} + + virtual void finish_req(uint64_t addr){ + assert(!is_uncached()); + coh->finish_resp(addr, policy->cmd_for_finish(coh_id)); + } +}; + // common behavior for cached outer ports -template requires C_DERIVE(OPUC, OuterCohPortUncached) +template requires C_DERIVE(OPUC, OuterCohPortCachedBase) class OuterCohPortT : public OPUC { protected: @@ -147,13 +161,9 @@ class OuterCohPortT : public OPUC return std::make_pair(hit, writeback); } - virtual void finish_req(uint64_t addr){ - assert(!OPUC::is_uncached()); - OPUC::coh->finish_resp(addr); - } }; -typedef OuterCohPortT OuterCohPort; +typedef OuterCohPortT OuterCohPort; class InnerCohPortUncached : public InnerCohPortBase { @@ -167,7 +177,7 @@ class InnerCohPortUncached : public InnerCohPortBase if (data_inner && data) data_inner->copy(data); policy->meta_after_grant(cmd, meta, meta_inner); cache->hook_read(addr, ai, s, w, hit, meta, data, delay); - if(cmd.id == -1) finish_resp(addr); + if(!hit) finish_record(addr, policy->cmd_for_finish(cmd.id)); } virtual void writeback_resp(uint64_t addr, CMDataBase *data_inner, CMMetadataBase *meta_inner, coh_cmd_t cmd, uint64_t *delay) { @@ -274,11 +284,16 @@ class InnerCohPortUncached : public InnerCohPortBase template requires C_DERIVE(IPUC, InnerCohPortUncached) class InnerCohPortT : public IPUC { +private: + // record the pending finish message from inner caches + // replace the single storage to a set in multi-thread sim + uint64_t addr_pending_finish; + int32_t id_pending_finish; protected: using IPUC::coh; using IPUC::outer; public: - InnerCohPortT(policy_ptr policy) : IPUC(policy) {} + InnerCohPortT(policy_ptr policy) : IPUC(policy), addr_pending_finish(0) {} virtual ~InnerCohPortT() {} virtual std::pair probe_req(uint64_t addr, CMMetadataBase *meta, CMDataBase *data, coh_cmd_t cmd, uint64_t *delay) { @@ -294,8 +309,23 @@ class InnerCohPortT : public IPUC return std::make_pair(hit, writeback); } - virtual void finish_resp(uint64_t addr){ - outer->finish_req(addr); + // record pending finish + virtual void finish_record(uint64_t addr, coh_cmd_t outer_cmd) { + if(outer_cmd.id == -1) { + outer->finish_req(addr); + } else { + addr_pending_finish = addr; + id_pending_finish = outer_cmd.id; + } + } + + // only forward the finish message recorded by previous acquire + virtual void finish_resp(uint64_t addr, coh_cmd_t outer_cmd) { + assert(addr_pending_finish == 0 || (addr_pending_finish == addr && id_pending_finish == outer_cmd.id)); + if(addr_pending_finish == addr && id_pending_finish == outer_cmd.id) { + outer->finish_req(addr); + addr_pending_finish = 0; + } } }; @@ -334,7 +364,7 @@ class CoreInterface : public InnerCohPortUncached, public CoreInterfaceBase { auto cmd = policy->cmd_for_read(); auto [meta, data, ai, s, w, hit] = access_line(addr, cmd, delay); cache->hook_read(addr, ai, s, w, hit, meta, data, delay); - outer->finish_req(addr); + if(!hit) outer->finish_req(addr); return data; } @@ -345,7 +375,7 @@ class CoreInterface : public InnerCohPortUncached, public CoreInterfaceBase { meta->to_dirty(); if(data) data->copy(m_data); cache->hook_write(addr, ai, s, w, hit, false, meta, data, delay); - outer->finish_req(addr); + if(!hit) outer->finish_req(addr); } virtual void flush(uint64_t addr, uint64_t *delay) { addr = normalize(addr); flush_line(addr, policy->cmd_for_flush(), delay); } @@ -455,8 +485,8 @@ class SliceDispatcher : public CohMasterBase virtual void query_loc_resp(uint64_t addr, std::list *locs){ cohm[hasher(addr)]->query_loc_resp(addr, locs); } - virtual void finish_resp(uint64_t addr){ - cohm[hasher(addr)]->finish_resp(addr); + virtual void finish_resp(uint64_t addr, coh_cmd_t cmd){ + cohm[hasher(addr)]->finish_resp(addr, cmd); } }; diff --git a/cache/exclusive.hpp b/cache/exclusive.hpp index 66454df..b4c3092 100644 --- a/cache/exclusive.hpp +++ b/cache/exclusive.hpp @@ -200,10 +200,11 @@ class ExclusiveInnerCohPortUncachedBroadcast : public InnerCohPortUncached if (data_inner && data) data_inner->copy(data); policy->meta_after_grant(cmd, meta, meta_inner); cache->hook_read(addr, ai, s, w, hit, meta, data, delay); - if(cmd.id == -1) finish_resp(addr); cache->meta_return_buffer(meta); cache->data_return_buffer(data); + + if(!hit) finish_record(addr, policy->cmd_for_finish(cmd.id)); } @@ -363,10 +364,11 @@ class ExclusiveInnerCohPortUncachedDirectory : public InnerCohPortUncached if (data_inner && data) data_inner->copy(data); policy->meta_after_grant(outer_cmd, meta, meta_inner); cache->hook_read(addr, ai, s, w, hit, meta, data, delay); - if(outer_cmd.id == -1) finish_resp(addr); // difficult to know when data is borrowed from buffer, just return it. cache->data_return_buffer(data); + + if(!hit) finish_record(addr, policy->cmd_for_finish(outer_cmd.id)); } protected: @@ -518,7 +520,7 @@ class ExclusiveInnerCohPortUncachedDirectory : public InnerCohPortUncached typedef InnerCohPortT ExclusiveInnerCohPortDirectory; -template requires C_DERIVE(OPUC, OuterCohPortUncached) +template requires C_DERIVE(OPUC, OuterCohPortCachedBase) class ExclusiveOuterCohPortBroadcastT : public OPUC { protected: @@ -564,17 +566,12 @@ class ExclusiveOuterCohPortBroadcastT : public OPUC return std::make_pair(hit||probe_hit, writeback); } - virtual void finish_req(uint64_t addr){ - assert(!OPUC::is_uncached()); - OPUC::coh->finish_resp(addr); - } - }; -typedef ExclusiveOuterCohPortBroadcastT ExclusiveOuterCohPortBroadcast; +typedef ExclusiveOuterCohPortBroadcastT ExclusiveOuterCohPortBroadcast; -template requires C_DERIVE(OPUC, OuterCohPortUncached) +template requires C_DERIVE(OPUC, OuterCohPortCachedBase) class ExclusiveOuterCohPortDirectoryT : public OPUC { protected: @@ -620,14 +617,9 @@ class ExclusiveOuterCohPortDirectoryT : public OPUC return std::make_pair(hit||probe_hit, writeback); } - virtual void finish_req(uint64_t addr){ - assert(!OPUC::is_uncached()); - OPUC::coh->finish_resp(addr); - } - }; -typedef ExclusiveOuterCohPortDirectoryT ExclusiveOuterCohPortDirectory; +typedef ExclusiveOuterCohPortDirectoryT ExclusiveOuterCohPortDirectory; template using ExclusiveL2CacheBroadcast = CoherentCacheNorm; From e8739de7b47385f90da5504aeb60f3c3a7ce45ec Mon Sep 17 00:00:00 2001 From: wangzd12138 Date: Fri, 7 Jun 2024 22:43:06 +0800 Subject: [PATCH 6/6] lower cache of uncached should call finish_resp instead of finish_req --- cache/coherence.hpp | 9 +++------ cache/exclusive.hpp | 2 ++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/cache/coherence.hpp b/cache/coherence.hpp index 37bc612..0335279 100644 --- a/cache/coherence.hpp +++ b/cache/coherence.hpp @@ -178,6 +178,7 @@ class InnerCohPortUncached : public InnerCohPortBase policy->meta_after_grant(cmd, meta, meta_inner); cache->hook_read(addr, ai, s, w, hit, meta, data, delay); if(!hit) finish_record(addr, policy->cmd_for_finish(cmd.id)); + if(cmd.id == -1) finish_resp(addr, policy->cmd_for_finish(cmd.id)); } virtual void writeback_resp(uint64_t addr, CMDataBase *data_inner, CMMetadataBase *meta_inner, coh_cmd_t cmd, uint64_t *delay) { @@ -311,12 +312,8 @@ class InnerCohPortT : public IPUC // record pending finish virtual void finish_record(uint64_t addr, coh_cmd_t outer_cmd) { - if(outer_cmd.id == -1) { - outer->finish_req(addr); - } else { - addr_pending_finish = addr; - id_pending_finish = outer_cmd.id; - } + addr_pending_finish = addr; + id_pending_finish = outer_cmd.id; } // only forward the finish message recorded by previous acquire diff --git a/cache/exclusive.hpp b/cache/exclusive.hpp index b4c3092..01b4e1a 100644 --- a/cache/exclusive.hpp +++ b/cache/exclusive.hpp @@ -205,6 +205,7 @@ class ExclusiveInnerCohPortUncachedBroadcast : public InnerCohPortUncached cache->data_return_buffer(data); if(!hit) finish_record(addr, policy->cmd_for_finish(cmd.id)); + if(cmd.id == -1) finish_resp(addr, policy->cmd_for_finish(cmd.id)); } @@ -369,6 +370,7 @@ class ExclusiveInnerCohPortUncachedDirectory : public InnerCohPortUncached cache->data_return_buffer(data); if(!hit) finish_record(addr, policy->cmd_for_finish(outer_cmd.id)); + if(outer_cmd.id == -1) finish_resp(addr, policy->cmd_for_finish(outer_cmd.id)); } protected: