From 707aab0c955e97abed6bd0780eb47cd38e7b1843 Mon Sep 17 00:00:00 2001 From: Slobodan Predolac Date: Tue, 16 Sep 2025 13:25:42 -0700 Subject: [PATCH] [pa-bench] Add clock to pa benchmark --- test/stress/pa/pa_data_preprocessor.cpp | 20 ++++++----- test/stress/pa/pa_microbench.c | 45 ++++++++++++++++++++----- 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/test/stress/pa/pa_data_preprocessor.cpp b/test/stress/pa/pa_data_preprocessor.cpp index 757f37bb..44e84e8c 100644 --- a/test/stress/pa/pa_data_preprocessor.cpp +++ b/test/stress/pa/pa_data_preprocessor.cpp @@ -16,13 +16,14 @@ * HPA: shard_ind_int,addr_int,nsecs_int,probe,size_int * SEC: process_id,thread_id,thread_name,nsecs_int,_c4,sec_ptr_int,sec_shard_ptr_int,edata_ptr_int,size_int,is_frequent_reuse_int * - * Output format (4 columns): - * shard_ind_int,operation_index,size_or_alloc_index,is_frequent + * Output format (5 columns): + * shard_ind_int,operation_index,size_or_alloc_index,nsecs,is_frequent * where: * - shard_ind_int: shard index as integer * - operation_index: 0=alloc, 1=dalloc * - size_or_alloc_index: for alloc operations show bytes, * for dalloc operations show index of corresponding alloc + * - nsecs: nanonosec of some monotonic clock * - is_frequent: 1 if frequent reuse allocation, 0 otherwise */ @@ -250,14 +251,14 @@ parse_sec_line( void write_output_header(std::ofstream &output) { - output << "shard_ind,operation,size_or_alloc_index,is_frequent\n"; + output << "shard_ind,operation,size_or_alloc_index,nsecs,is_frequent\n"; } void write_output_event(std::ofstream &output, int shard_ind, int operation, - size_t value, bool is_frequent) { - output << shard_ind << "," << operation << "," << value << "," - << (is_frequent ? 1 : 0) << "\n"; + size_t value, uint64_t nsecs, bool is_frequent) { + output << shard_ind << "," << operation << "," << value << "," << nsecs + << "," << (is_frequent ? 1 : 0) << "\n"; } size_t @@ -319,7 +320,7 @@ process_trace_file(const std::string &input_filename, if (is_alloc_operation(event.probe)) { /* This is an allocation */ write_output_event(output, event.shard_ind, 0, - event.size, event.is_frequent); + event.size, event.nsecs, event.is_frequent); /* Track this allocation with the current sequence number */ tracker.add_allocation(event.addr, event.size, @@ -335,7 +336,8 @@ process_trace_file(const std::string &input_filename, assert(event.nsecs >= record->nsecs); /* Found matching allocation with valid timing */ write_output_event(output, event.shard_ind, 1, - record->alloc_index, event.is_frequent); + record->alloc_index, event.nsecs, + event.is_frequent); tracker.remove_allocation(event.addr); output_count++; /* Count this deallocation */ } else { @@ -390,7 +392,7 @@ main(int argc, char *argv[]) { << " output_file - Output file for simulator with format:" << std::endl; std::cerr - << " shard_ind,operation,size_or_alloc_index,is_frequent" + << " shard_ind,operation,size_or_alloc_index,nsecs,is_frequent" << std::endl; std::cerr << std::endl; std::cerr << "Output format:" << std::endl; diff --git a/test/stress/pa/pa_microbench.c b/test/stress/pa/pa_microbench.c index 4ad3652d..c4706b04 100644 --- a/test/stress/pa/pa_microbench.c +++ b/test/stress/pa/pa_microbench.c @@ -32,10 +32,11 @@ typedef enum { PA_ALLOC = 0, PA_DALLOC = 1 } pa_op_t; typedef struct { - int shard_ind; - pa_op_t operation; - size_t size_or_alloc_index; - int is_frequent; + int shard_ind; + pa_op_t operation; + size_t size_or_alloc_index; + uint64_t nsecs; + int is_frequent; } pa_event_t; typedef struct { @@ -73,6 +74,29 @@ static shard_infrastructure_t *g_shard_infra = NULL; /* Per-shard PA infrastructure */ static pa_central_t g_pa_central; /* Global PA central */ +/* Override for curtime */ +static hpa_hooks_t hpa_hooks_override; +static nstime_t cur_time_clock; + +void +curtime(nstime_t *r_time, bool first_reading) { + if (first_reading) { + nstime_init_zero(r_time); + } + *r_time = cur_time_clock; +} + +static void +set_clock(uint64_t nsecs) { + nstime_init(&cur_time_clock, nsecs); +} + +static void +init_hpa_hooks() { + hpa_hooks_override = hpa_hooks_default; + hpa_hooks_override.curtime = curtime; +} + static void cleanup_pa_infrastructure(int num_shards); static bool @@ -125,8 +149,9 @@ initialize_pa_infrastructure(int num_shards) { } /* Initialize PA central with HPA enabled */ + init_hpa_hooks(); if (pa_central_init(&g_pa_central, central_base, true /* hpa */, - &hpa_hooks_default)) { + &hpa_hooks_override)) { printf("DEBUG: Failed to initialize PA central\n"); base_delete(tsd_tsdn(tsd_fetch()), central_base); free(g_shard_stats); @@ -237,14 +262,15 @@ static bool parse_csv_line(const char *line, pa_event_t *event) { /* Expected format: shard_ind,operation,size_or_alloc_index,is_frequent */ int operation; - int fields = sscanf(line, "%d,%d,%zu,%d", &event->shard_ind, &operation, - &event->size_or_alloc_index, &event->is_frequent); + int fields = sscanf(line, "%d,%d,%zu,%lu,%d", &event->shard_ind, + &operation, &event->size_or_alloc_index, &event->nsecs, + &event->is_frequent); - if (fields < 3) { /* is_frequent is optional */ + if (fields < 4) { /* is_frequent is optional */ return false; } - if (fields == 3) { + if (fields == 4) { event->is_frequent = 0; /* Default value */ } @@ -393,6 +419,7 @@ simulate_trace( continue; } + set_clock(event->nsecs); switch (event->operation) { case PA_ALLOC: { size_t size = event->size_or_alloc_index;