Skip to content

Commit 99ebe42

Browse files
committed
update
1 parent 8774de7 commit 99ebe42

5 files changed

Lines changed: 117 additions & 22 deletions

File tree

include/cxlcontroller.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ class CXLController : public CXLSwitch {
264264
void insert_one(thread_info &t_info, lbr &lbr);
265265
int insert(uint64_t timestamp, uint64_t tid, lbr lbrs[32], cntr counters[32]);
266266
int insert(uint64_t timestamp, uint64_t tid, uint64_t phys_addr, uint64_t virt_addr, int index) override;
267+
void record_cxl_access(uint64_t timestamp, uint64_t tid, uint64_t addr, bool is_write);
267268
void delete_entry(uint64_t addr, uint64_t length) override;
268269
void perform_migration();
269270
std::optional<uint64_t> access_cache(uint64_t addr, uint64_t timestamp) { return lru_cache.get(addr, timestamp); }

include/cxlendpoint.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,8 @@ class CXLMemExpander : public CXLEndPoint {
447447
void set_epoch(int epoch) override;
448448
void free_stats(double size) override;
449449
int insert(uint64_t timestamp, uint64_t tid, uint64_t phys_addr, uint64_t virt_addr, int index) override;
450+
int record_access(uint64_t timestamp, uint64_t tid, uint64_t phys_addr, uint64_t virt_addr, int index,
451+
bool is_write);
450452
double calculate_latency(const std::vector<std::tuple<uint64_t, uint64_t>> &elem,
451453
double dramlatency) override; // traverse the tree to calculate the latency
452454
double calculate_bandwidth(const std::vector<std::tuple<uint64_t, uint64_t>> &elem) override;
@@ -532,6 +534,8 @@ class CXLSwitch : public CXLEndPoint {
532534
const std::vector<std::tuple<uint64_t, uint64_t>> &accesses,
533535
const thread_info &t_info, double dramlatency);
534536
int insert(uint64_t timestamp, uint64_t tid, uint64_t phys_addr, uint64_t virt_addr, int index) override;
537+
int record_access(uint64_t timestamp, uint64_t tid, uint64_t phys_addr, uint64_t virt_addr, int index,
538+
bool is_write);
535539
void delete_entry(uint64_t addr, uint64_t length) override;
536540
virtual std::tuple<double, std::vector<uint64_t>> calculate_congestion();
537541
void set_epoch(int epoch) override;

src/cxlcontroller.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,26 @@ int CXLController::insert(uint64_t timestamp, uint64_t tid, uint64_t phys_addr,
411411
return res;
412412
}
413413

414+
void CXLController::record_cxl_access(uint64_t timestamp, uint64_t tid, uint64_t addr, bool is_write) {
415+
this->counter.inc_remote();
416+
417+
int endpoint_id = 0;
418+
if (!this->cur_expanders.empty() && this->cur_expanders.front() != nullptr) {
419+
endpoint_id = this->cur_expanders.front()->id;
420+
}
421+
422+
int ret = CXLSwitch::record_access(timestamp, tid, addr, addr, endpoint_id, is_write);
423+
if (ret == 0) {
424+
for (auto *expander : this->cur_expanders) {
425+
if (expander == nullptr || expander->id != endpoint_id) {
426+
continue;
427+
}
428+
expander->record_access(timestamp, tid, addr, addr, endpoint_id, is_write);
429+
break;
430+
}
431+
}
432+
}
433+
414434
int CXLController::insert(uint64_t timestamp, uint64_t tid, lbr lbrs[32], cntr counters[32]) {
415435
// LBR
416436
for (int i = 0; i < 32; i++) {

src/cxlendpoint.cpp

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,56 @@ int CXLMemExpander::insert(uint64_t timestamp, uint64_t tid, uint64_t phys_addr,
310310
}
311311
return 0;
312312
}
313+
314+
int CXLMemExpander::record_access(uint64_t timestamp, uint64_t tid, uint64_t phys_addr, uint64_t virt_addr, int index,
315+
bool is_write) {
316+
if (index != this->id) {
317+
return 0;
318+
}
319+
320+
(void)virt_addr;
321+
last_timestamp = last_timestamp > timestamp ? last_timestamp : timestamp;
322+
process_queued_requests(timestamp);
323+
324+
CXLRequest req{};
325+
req.timestamp = timestamp;
326+
req.address = phys_addr;
327+
req.tid = tid;
328+
req.is_read = !is_write;
329+
req.is_write = is_write;
330+
req.issue_time = timestamp;
331+
req.complete_time = timestamp;
332+
333+
if (!can_accept_request()) {
334+
this->counter.inc_hit_old();
335+
return 0;
336+
}
337+
338+
{
339+
std::lock_guard<std::mutex> lock(queue_mutex_);
340+
request_queue_.push_back(req);
341+
}
342+
343+
for (auto it = this->occupation.cbegin(); it != this->occupation.cend(); ++it) {
344+
if (it->address == phys_addr) {
345+
this->occupation.erase(it);
346+
break;
347+
}
348+
}
349+
350+
this->occupation.emplace_back(timestamp, phys_addr, is_write ? 0 : 1);
351+
this->address_cache.insert(phys_addr);
352+
this->invalidate_cache();
353+
354+
if (is_write) {
355+
this->counter.inc_store();
356+
return 1;
357+
}
358+
359+
this->counter.inc_load();
360+
return 2;
361+
}
362+
313363
std::vector<std::tuple<uint64_t, uint64_t>> CXLMemExpander::get_access(uint64_t timestamp) {
314364
last_counter = CXLMemExpanderEvent(counter);
315365

@@ -641,6 +691,44 @@ int CXLSwitch::insert(uint64_t timestamp, uint64_t tid, uint64_t phys_addr, uint
641691
return 0;
642692
}
643693

694+
int CXLSwitch::record_access(uint64_t timestamp, uint64_t tid, uint64_t phys_addr, uint64_t virt_addr, int index,
695+
bool is_write) {
696+
SPDLOG_DEBUG("CXLSwitch record_access phys_addr={}, virt_addr={}, index={}, is_write={} for switch id:{}",
697+
phys_addr, virt_addr, index, is_write, this->id);
698+
699+
for (auto &expander : this->expanders) {
700+
if (expander == nullptr) {
701+
continue;
702+
}
703+
int ret = expander->record_access(timestamp, tid, phys_addr, virt_addr, index, is_write);
704+
if (ret == 1) {
705+
this->counter.inc_store();
706+
return 1;
707+
}
708+
if (ret == 2) {
709+
this->counter.inc_load();
710+
return 2;
711+
}
712+
}
713+
714+
for (auto &sw : this->switches) {
715+
if (sw == nullptr) {
716+
continue;
717+
}
718+
int ret = sw->record_access(timestamp, tid, phys_addr, virt_addr, index, is_write);
719+
if (ret == 1) {
720+
this->counter.inc_store();
721+
return 1;
722+
}
723+
if (ret == 2) {
724+
this->counter.inc_load();
725+
return 2;
726+
}
727+
}
728+
729+
return 0;
730+
}
731+
644732
// Implementation of new CXL queue management and pipeline methods
645733
bool CXLMemExpander::can_accept_request() const {
646734
std::lock_guard<std::mutex> lock(queue_mutex_);

src/main_server.cc

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,13 +1382,7 @@ void ThreadPerConnectionServer::handle_request(int client_fd, int thread_id, Ser
13821382
total_reads++;
13831383

13841384
// Propagate stats through CXL topology (switches/expanders)
1385-
controller->counter.inc_local();
1386-
for (auto &sw : controller->switches) {
1387-
sw->insert(req.timestamp, (uint64_t)thread_id, req.addr, req.addr, 0);
1388-
}
1389-
for (auto &ep : controller->expanders) {
1390-
ep->insert(req.timestamp, (uint64_t)thread_id, req.addr, req.addr, ep->id);
1391-
}
1385+
controller->record_cxl_access(req.timestamp, (uint64_t)thread_id, req.addr, false);
13921386

13931387
log_periodic_stats("READ", total_reads.load());
13941388
} else { // WRITE
@@ -1468,13 +1462,7 @@ void ThreadPerConnectionServer::handle_request(int client_fd, int thread_id, Ser
14681462
total_writes++;
14691463

14701464
// Propagate stats through CXL topology (switches/expanders)
1471-
controller->counter.inc_local();
1472-
for (auto &sw : controller->switches) {
1473-
sw->insert(req.timestamp, (uint64_t)thread_id, req.addr, req.addr, 0);
1474-
}
1475-
for (auto &ep : controller->expanders) {
1476-
ep->insert(req.timestamp, (uint64_t)thread_id, req.addr, req.addr, ep->id);
1477-
}
1465+
controller->record_cxl_access(req.timestamp, (uint64_t)thread_id, req.addr, true);
14781466

14791467
log_periodic_stats("WRITE", total_writes.load());
14801468
}
@@ -2139,10 +2127,7 @@ int ThreadPerConnectionServer::poll_pgas_shm_requests() {
21392127

21402128
total_reads++;
21412129

2142-
// PGAS server mode may be used with a minimal topology file whose
2143-
// switch objects are not fully materialized. Keep the authoritative
2144-
// operation counters independent from that optional topology walk.
2145-
controller->counter.inc_local();
2130+
controller->record_cxl_access(request_ts, static_cast<uint64_t>(i), addr, false);
21462131

21472132
log_periodic_stats("PGAS_READ", total_reads.load());
21482133
__atomic_thread_fence(__ATOMIC_RELEASE);
@@ -2173,10 +2158,7 @@ int ThreadPerConnectionServer::poll_pgas_shm_requests() {
21732158
slot->latency_ns = (uint64_t)(base_latency + fabric_latency_ns);
21742159
total_writes++;
21752160

2176-
// PGAS server mode may be used with a minimal topology file whose
2177-
// switch objects are not fully materialized. Keep the authoritative
2178-
// operation counters independent from that optional topology walk.
2179-
controller->counter.inc_local();
2161+
controller->record_cxl_access(request_ts, static_cast<uint64_t>(i), addr, true);
21802162

21812163
log_periodic_stats("PGAS_WRITE", total_writes.load());
21822164
__atomic_thread_fence(__ATOMIC_RELEASE);

0 commit comments

Comments
 (0)