88 * Copyright 2025 Regents of the University of California
99 * UC Santa Cruz Sluglab.
1010 */
11-
1211#ifndef CXLMEMSIM_CXLCOUNTER_H
1312#define CXLMEMSIM_CXLCOUNTER_H
1413
1514#include < cstdint>
16- #include < map>
17- #include < tuple>
18- #include < vector>
19-
15+ #include < atomic>
16+ #include < concepts>
17+ #include < source_location>
18+ #include < expected>
19+ #include < string>
20+ #include < format>
2021/* * TODO: Whether to using the pebs to record the state. add back invalidation migrate huge/ page and prefetch*/
22+ const char loadName[] = " load" ;
23+ const char storeName[] = " store" ;
24+ const char conflictName[] = " conflict" ;
25+ const char migrateInName[] = " migrate_in" ;
26+ const char migrateOutName[] = " migrate_out" ;
27+ const char hitOldName[] = " hit_old" ;
28+ const char localName[] = " local" ;
29+ const char remoteName[] = " remote" ;
30+ const char hitmName[] = " hitm" ;
31+
32+ // 基础计数器模板类
33+ template <const char * Name>
34+ class AtomicCounter {
35+ public:
36+ std::atomic<uint64_t > value = 0 ;
37+ constexpr AtomicCounter () noexcept = default;
38+ constexpr AtomicCounter (const AtomicCounter& other) noexcept : value(other.value.load()) { // 复制构造函数
39+
40+ };
41+ AtomicCounter& operator =(const AtomicCounter&other) {
42+ if (this != &other) {
43+ value.store (other.value .load ());
44+ }
45+ return *this ;
46+ };
47+
48+ // C++26允许constexpr修饰原子操作
49+ constexpr void increment () noexcept {
50+ value.fetch_add (1 , std::memory_order_relaxed);
51+ }
52+
53+ constexpr uint64_t get () const noexcept {
54+ return value.load (std::memory_order_relaxed);
55+ }
56+
57+ constexpr operator uint64_t () const noexcept {
58+ return get ();
59+ }
60+
61+ // 用于可能需要记录的事件日志
62+ void log_increment (std::source_location loc = std::source_location::current()) const {
63+ // 未来可以实现日志记录
64+ }
65+ };
66+ // 确保AtomicCounter满足Counter概念
67+ template <const char * Name>
68+ inline constexpr bool implements_counter_concept = requires (AtomicCounter<Name> t) {
69+ { t.value } -> std::convertible_to<uint64_t >;
70+ { t.increment () } -> std::same_as<void >;
71+ };
72+
73+
74+ template <const char * Name>
75+ struct std ::formatter<AtomicCounter<Name>> {
76+ constexpr auto parse (std::format_parse_context& ctx) -> decltype(ctx.begin()) {
77+ return ctx.end ();
78+ }
79+
80+ template <typename FormatContext>
81+ constexpr auto format (const AtomicCounter<Name>& counter, FormatContext& ctx) const
82+ -> decltype(ctx.out())
83+ {
84+ // 直接使用format_to避免嵌套std::format调用
85+ return format_to (ctx.out (), " {}" , counter.get ());
86+ }
87+ };
88+
89+ // 使用C++20的enum class和强类型枚举
90+ enum class EventType {
91+ Load,
92+ Store,
93+ Conflict,
94+ MigrateIn,
95+ MigrateOut,
96+ HitOld,
97+ Local,
98+ Remote,
99+ Hitm
100+ };
101+
102+ // 开关事件计数器
21103class CXLSwitchEvent {
22104public:
23- uint64_t load = 0 ;
24- uint64_t store = 0 ;
25- uint64_t conflict = 0 ;
26-
27- CXLSwitchEvent () = default ;
28- CXLSwitchEvent (const CXLSwitchEvent &other) = default ;
29- void inc_load ();
30- void inc_store ();
31- void inc_conflict ();
105+ AtomicCounter<loadName> load;
106+ AtomicCounter<storeName> store;
107+ AtomicCounter<conflictName> conflict;
108+
109+ constexpr CXLSwitchEvent () noexcept = default;
110+
111+ // 使用C++20的模板元编程和编译期字符串实现更灵活的接口
112+ template <EventType Type>
113+ constexpr void increment () noexcept {
114+ if constexpr (Type == EventType::Load) {
115+ load.increment ();
116+ } else if constexpr (Type == EventType::Store) {
117+ store.increment ();
118+ } else if constexpr (Type == EventType::Conflict) {
119+ conflict.increment ();
120+ }
121+ }
122+
123+ constexpr void inc_load () noexcept { load.increment (); }
124+ constexpr void inc_store () noexcept { store.increment (); }
125+ constexpr void inc_conflict () noexcept { conflict.increment (); }
126+
127+ // 使用C++23的auto模板参数实现更灵活的统计功能
128+ template <auto Field>
129+ constexpr uint64_t get () const noexcept {
130+ if constexpr (Field == &CXLSwitchEvent::load) {
131+ return load;
132+ } else if constexpr (Field == &CXLSwitchEvent::store) {
133+ return store;
134+ } else if constexpr (Field == &CXLSwitchEvent::conflict) {
135+ return conflict;
136+ }
137+ }
32138};
139+
140+ // 内存扩展器事件计数器
33141class CXLMemExpanderEvent {
34142public:
35- uint64_t load = 0 ;
36- uint64_t store = 0 ;
37- uint64_t migrate = 0 ;
38- uint64_t hit_old = 0 ;
39-
40- CXLMemExpanderEvent () = default ;
41- CXLMemExpanderEvent (const CXLMemExpanderEvent &other) = default ;
42- void inc_load ();
43- void inc_store ();
44- void inc_migrate ();
45- void inc_hit_old ();
143+ AtomicCounter<loadName> load;
144+ AtomicCounter<storeName> store;
145+ AtomicCounter<migrateInName> migrate_in;
146+ AtomicCounter<migrateOutName> migrate_out;
147+ AtomicCounter<hitOldName> hit_old;
148+
149+ constexpr CXLMemExpanderEvent () noexcept = default;
150+
151+ template <EventType Type>
152+ constexpr void increment () noexcept {
153+ if constexpr (Type == EventType::Load) {
154+ load.increment ();
155+ } else if constexpr (Type == EventType::Store) {
156+ store.increment ();
157+ } else if constexpr (Type == EventType::MigrateIn) {
158+ migrate_in.increment ();
159+ } else if constexpr (Type == EventType::MigrateOut) {
160+ migrate_out.increment ();
161+ } else if constexpr (Type == EventType::HitOld) {
162+ hit_old.increment ();
163+ }
164+ }
165+
166+ constexpr void inc_load () noexcept { load.increment (); }
167+ constexpr void inc_store () noexcept { store.increment (); }
168+ constexpr void inc_migrate_in () noexcept { migrate_in.increment (); }
169+ constexpr void inc_migrate_out () noexcept { migrate_out.increment (); }
170+ constexpr void inc_hit_old () noexcept { hit_old.increment (); }
171+
172+ // 统计方法
173+ constexpr uint64_t total_operations () const noexcept {
174+ return load + store + migrate_in + migrate_out + hit_old;
175+ }
176+
177+ // 使用C++23的expected获取操作结果
178+ std::expected<uint64_t , std::string> safe_get (EventType type) const noexcept {
179+ switch (type) {
180+ case EventType::Load: return load;
181+ case EventType::Store: return store;
182+ case EventType::MigrateIn: return migrate_in;
183+ case EventType::MigrateOut: return migrate_out;
184+ case EventType::HitOld: return hit_old;
185+ default : return std::unexpected (std::string (" Invalid event type for CXLMemExpanderEvent" ));
186+ }
187+ }
46188};
189+
190+ // 通用计数器
47191class CXLCounter {
48192public:
49- uint64_t local = 0 ;
50- uint64_t remote = 0 ;
51- uint64_t hitm = 0 ;
52-
53- CXLCounter () = default ;
54- CXLCounter (const CXLCounter &other) = default ;
55- void inc_local ();
56- void inc_remote ();
57- void inc_hitm ();
193+ AtomicCounter<localName> local;
194+ AtomicCounter<remoteName> remote;
195+ AtomicCounter<hitmName> hitm;
196+
197+ constexpr CXLCounter () noexcept = default;
198+
199+ template <EventType Type>
200+ constexpr void increment () noexcept {
201+ if constexpr (Type == EventType::Local) {
202+ local.increment ();
203+ } else if constexpr (Type == EventType::Remote) {
204+ remote.increment ();
205+ } else if constexpr (Type == EventType::Hitm) {
206+ hitm.increment ();
207+ }
208+ }
209+
210+ constexpr void inc_local () noexcept { local.increment (); }
211+ constexpr void inc_remote () noexcept { remote.increment (); }
212+ constexpr void inc_hitm () noexcept { hitm.increment (); }
213+
214+ // 便捷方法:计算本地命中率
215+ constexpr double local_hit_ratio () const noexcept {
216+ uint64_t total = local + remote;
217+ return total > 0 ? static_cast <double >(local) / total : 0.0 ;
218+ }
58219};
59220
60- #endif // CXLMEMSIM_CXLCOUNTER_H
221+ // 实现部分现在可以以内联方式编写,不需要单独的.cpp文件
222+ // 但为了兼容性,我们仍保留.cpp文件的实现
223+
224+ #endif // CXLMEMSIM_CXLCOUNTER_H
0 commit comments