Skip to content

Commit 8640ad8

Browse files
committed
add heataware policy
1 parent e3538dd commit 8640ad8

File tree

8 files changed

+455
-193
lines changed

8 files changed

+455
-193
lines changed

include/cxlcontroller.h

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,30 @@ class AllocationPolicy : public Policy {
3838

3939
class MigrationPolicy : public Policy {
4040
public:
41-
MigrationPolicy();
42-
std::vector<std::tuple<uint64_t, uint64_t>> get_migration_list(CXLController *controller);
43-
// migration related
44-
// 1. get the migration list
45-
// 2. do the migration
46-
// 3. update the counter
47-
// 4. update the occupation map
48-
// 5. update the latency and bandwidth
49-
// 6. update the ring buffer
50-
// 7. update the rob info
51-
// 8. update the thread info
41+
MigrationPolicy() = default;
42+
virtual ~MigrationPolicy() = default;
43+
44+
// 基本的compute_once方法,决定是否需要执行迁移
45+
int compute_once(CXLController* controller) override {
46+
auto migration_list = get_migration_list(controller);
47+
return migration_list.empty() ? 0 : 1;
48+
}
49+
50+
// 获取需要迁移的地址列表
51+
std::vector<std::tuple<uint64_t, uint64_t>> get_migration_list(CXLController *controller) {
52+
std::vector<std::tuple<uint64_t, uint64_t>> migration_list;
53+
// 基类提供空实现
54+
return migration_list;
55+
}
56+
// 判断特定地址是否应该迁移
57+
virtual bool should_migrate(uint64_t addr, uint64_t timestamp, int current_device) {
58+
return false;
59+
}
60+
61+
// 为给定地址选择最佳的目标设备
62+
virtual int select_target_device(uint64_t addr, int current_device, CXLController* controller) {
63+
return -1; // -1表示不迁移
64+
}
5265
};
5366

5467
// need to give a timeout and will be added latency later,
@@ -171,6 +184,7 @@ class CXLController : public CXLSwitch {
171184
double latency_lat{};
172185
double bandwidth_lat{};
173186
double dramlatency;
187+
std::unordered_map<int, CXLMemExpander*> device_map;
174188
// ring buffer
175189
std::queue<lbr> ring_buffer;
176190
// rob info
@@ -196,6 +210,7 @@ class CXLController : public CXLSwitch {
196210
void set_stats(mem_stats stats);
197211
static void set_process_info(const proc_info &process_info);
198212
static void set_thread_info(const proc_info &thread_info);
213+
void perform_migration();
199214
// 添加缓存访问方法
200215
std::optional<uint64_t> access_cache(uint64_t addr, uint64_t timestamp) { return lru_cache.get(addr, timestamp); }
201216

@@ -259,9 +274,9 @@ template <> struct std::formatter<CXLController> {
259274

260275
// 打印全局计数器
261276
result += std::format(" Global Counter:\n");
262-
result += std::format(" Local: {}\n", controller.counter.local);
263-
result += std::format(" Remote: {}\n", controller.counter.remote);
264-
result += std::format(" HITM: {}\n", controller.counter.hitm);
277+
result += std::format(" Local: {}\n", controller.counter.local.get());
278+
result += std::format(" Remote: {}\n", controller.counter.remote.get());
279+
result += std::format(" HITM: {}\n", controller.counter.hitm.get());
265280

266281
// 打印拓扑结构(交换机和端点)
267282
result += "Topology:\n";
@@ -274,9 +289,9 @@ template <> struct std::formatter<CXLController> {
274289
// 打印交换机事件计数
275290
result += std::format("{}Switch:\n", indent);
276291
result += std::format("{} Events:\n", indent);
277-
result += std::format("{} Load: {}\n", indent, sw->counter.load);
278-
result += std::format("{} Store: {}\n", indent, sw->counter.store);
279-
result += std::format("{} Conflict: {}\n", indent, sw->counter.conflict);
292+
result += std::format("{} Load: {}\n", indent, sw->counter.load.get());
293+
result += std::format("{} Store: {}\n", indent, sw->counter.store.get());
294+
result += std::format("{} Conflict: {}\n", indent, sw->counter.conflict.get());
280295

281296
// 递归打印子交换机
282297
for (const auto &child : sw->switches) {
@@ -287,10 +302,11 @@ template <> struct std::formatter<CXLController> {
287302
for (const auto &endpoint : sw->expanders) {
288303
result += std::format("{}Expander:\n", indent + " ");
289304
result += std::format("{} Events:\n", indent + " ");
290-
result += std::format("{} Load: {}\n", indent + " ", endpoint->counter.load);
291-
result += std::format("{} Store: {}\n", indent + " ", endpoint->counter.store);
292-
result += std::format("{} Migrate: {}\n", indent + " ", endpoint->counter.migrate);
293-
result += std::format("{} Hit Old: {}\n", indent + " ", endpoint->counter.hit_old);
305+
result += std::format("{} Load: {}\n", indent + " ", endpoint->counter.load.get());
306+
result += std::format("{} Store: {}\n", indent + " ", endpoint->counter.store.get());
307+
result += std::format("{} Migrate: {}\n", indent + " ", endpoint->counter.migrate_in.get());
308+
result += std::format("{} Migrate: {}\n", indent + " ", endpoint->counter.migrate_out.get());
309+
result += std::format("{} Hit Old: {}\n", indent + " ", endpoint->counter.hit_old.get());
294310
}
295311
};
296312

include/cxlcounter.h

Lines changed: 199 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8,53 +8,217 @@
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+
// 开关事件计数器
21103
class CXLSwitchEvent {
22104
public:
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+
// 内存扩展器事件计数器
33141
class CXLMemExpanderEvent {
34142
public:
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+
// 通用计数器
47191
class CXLCounter {
48192
public:
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

Comments
 (0)