Skip to content

Commit 70ce858

Browse files
Add per-request cost support (obj_cost) and cost-miss reporting (#309)
* support object cost * Update libCacheSim/bin/cachesim/main.c Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
1 parent 6ec428d commit 70ce858

11 files changed

Lines changed: 114 additions & 36 deletions

File tree

libCacheSim/bin/cachesim/main.c

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#endif
66
#include <assert.h>
77
#include <libgen.h>
8+
#include <math.h>
89

910
#include "internal.h"
1011
#include "libCacheSim/cache.h"
@@ -66,14 +67,31 @@ int main(int argc, char **argv) {
6667

6768
printf("\n");
6869
for (int i = 0; i < args.n_cache_size * args.n_eviction_algo; i++) {
69-
snprintf(output_str, 1024,
70-
"%s %s cache size %8ld%s, %lld req, miss ratio %.4lf, byte miss "
71-
"ratio %.4lf\n",
72-
args.reader->trace_path, result[i].cache_name,
73-
(long)(result[i].cache_size / size_unit), size_unit_str,
74-
(long long)result[i].n_req,
75-
(double)result[i].n_miss / (double)result[i].n_req,
76-
(double)result[i].n_miss_byte / (double)result[i].n_req_byte);
70+
double miss_ratio = result[i].n_req > 0
71+
? (double)result[i].n_miss / (double)result[i].n_req
72+
: 0.0;
73+
double cost_saving_ratio =
74+
result[i].n_req_cost > 0
75+
? 1.0 - result[i].n_miss_cost / result[i].n_req_cost
76+
: 0.0;
77+
bool show_cost = fabs(1 - cost_saving_ratio - miss_ratio) > 1e-9;
78+
79+
int n = snprintf(output_str, sizeof(output_str),
80+
"%s %s cache size %8ld%s, %lld req, miss ratio %.4lf",
81+
args.reader->trace_path, result[i].cache_name,
82+
(long)(result[i].cache_size / size_unit), size_unit_str,
83+
(long long)result[i].n_req, miss_ratio);
84+
if (!args.ignore_obj_size)
85+
n += snprintf(
86+
output_str + n, sizeof(output_str) - n, ", byte miss ratio %.4lf",
87+
result[i].n_req_byte > 0
88+
? (double)result[i].n_miss_byte / (double)result[i].n_req_byte
89+
: 0.0);
90+
if (show_cost)
91+
n += snprintf(output_str + n, sizeof(output_str) - n,
92+
", cost saving ratio %.4lf", cost_saving_ratio);
93+
snprintf(output_str + n, sizeof(output_str) - n, "\n");
94+
7795
printf("%s", output_str);
7896
fprintf(output_file, "%s", output_str);
7997
}

libCacheSim/bin/cachesim/sim.c

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ void simulate(reader_t *reader, cache_t *cache, int report_interval,
2525
uint64_t req_cnt = 0, miss_cnt = 0;
2626
uint64_t last_req_cnt = 0, last_miss_cnt = 0;
2727
uint64_t req_byte = 0, miss_byte = 0;
28+
double req_cost = 0, miss_cost = 0;
2829

2930
read_one_req(reader, req);
3031
uint64_t start_ts = (uint64_t)req->clock_time;
@@ -52,9 +53,11 @@ void simulate(reader_t *reader, cache_t *cache, int report_interval,
5253

5354
req_cnt++;
5455
req_byte += req->obj_size;
56+
req_cost += req->obj_cost;
5557
if (cache->get(cache, req) == false) {
5658
miss_cnt++;
5759
miss_byte += req->obj_size;
60+
miss_cost += req->obj_cost;
5861
}
5962
if (req->clock_time - last_report_ts >= (uint64_t)report_interval &&
6063
req->clock_time != 0) {
@@ -78,28 +81,30 @@ void simulate(reader_t *reader, cache_t *cache, int report_interval,
7881

7982
char output_str[1024];
8083
char size_str[64];
81-
82-
if (!ignore_obj_size) convert_size_to_str(cache->cache_size, size_str, 64);
83-
#pragma GCC diagnostic push
84-
// Removed unknown pragma warning
85-
if (!ignore_obj_size) {
86-
snprintf(output_str, 1024,
87-
"%s %s cache size %8s, %16lu req, miss ratio %.4lf, throughput "
88-
"%.2lf MQPS\n",
89-
reader->trace_path, detailed_cache_name, size_str,
90-
(unsigned long)req_cnt, (double)miss_cnt / (double)req_cnt,
91-
(double)req_cnt / 1000000.0 / runtime);
92-
} else {
93-
snprintf(output_str, 1024,
94-
"%s %s cache size %8lld, %16lu req, miss ratio %.4lf, throughput "
95-
"%.2lf MQPS\n",
96-
reader->trace_path, detailed_cache_name,
97-
(long long)cache->cache_size, (unsigned long)req_cnt,
98-
(double)miss_cnt / (double)req_cnt,
99-
(double)req_cnt / 1000000.0 / runtime);
100-
}
101-
102-
#pragma GCC diagnostic pop
84+
double miss_ratio = req_cnt > 0 ? (double)miss_cnt / (double)req_cnt : 0.0;
85+
double byte_miss_ratio =
86+
req_byte > 0 ? (double)miss_byte / (double)req_byte : 0.0;
87+
double cost_saving_ratio = 1.0 - (req_cost > 0 ? miss_cost / req_cost : 0.0);
88+
89+
if (!ignore_obj_size)
90+
convert_size_to_str(cache->cache_size, size_str, 64);
91+
else
92+
snprintf(size_str, sizeof(size_str), "%lld", (long long)cache->cache_size);
93+
94+
bool show_cost = fabs(1 - cost_saving_ratio - miss_ratio) > 1e-9;
95+
96+
int n = snprintf(output_str, sizeof(output_str),
97+
"%s %s cache size %8s, %16lu req, miss ratio %.4lf",
98+
reader->trace_path, detailed_cache_name, size_str,
99+
(unsigned long)req_cnt, miss_ratio);
100+
if (!ignore_obj_size)
101+
n += snprintf(output_str + n, sizeof(output_str) - n,
102+
", byte miss ratio %.4lf", byte_miss_ratio);
103+
if (show_cost)
104+
n += snprintf(output_str + n, sizeof(output_str) - n,
105+
", cost saving ratio %.4lf", cost_saving_ratio);
106+
snprintf(output_str + n, sizeof(output_str) - n, ", throughput %.2lf MQPS\n",
107+
(double)req_cnt / 1000000.0 / runtime);
103108
printf("%s", output_str);
104109
char *output_dir = rindex(ofilepath, '/');
105110
if (output_dir != NULL) {

libCacheSim/bin/cli_reader_utils.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ void parse_reader_params(const char *reader_params_str,
119119
strcasecmp(key, "size-col") == 0) {
120120
params->obj_size_field = (int)strtol(value, &end, 0);
121121
_check_parsed_result(end, params->obj_size_field);
122+
} else if (strcasecmp(key, "obj-cost-col") == 0 ||
123+
strcasecmp(key, "cost-col") == 0) {
124+
params->obj_cost_field = (int)strtol(value, &end, 0);
125+
_check_parsed_result(end, params->obj_cost_field);
122126
} else if (strcasecmp(key, "cnt-col") == 0) {
123127
params->cnt_field = (int)strtol(value, &end, 0);
124128
} else if (strcasecmp(key, "op-col") == 0) {

libCacheSim/include/libCacheSim/cache.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,10 @@ typedef struct {
7373
int64_t n_warmup_req;
7474
int64_t n_req;
7575
int64_t n_req_byte;
76+
double n_req_cost;
7677
int64_t n_miss;
7778
int64_t n_miss_byte;
79+
double n_miss_cost;
7880

7981
int64_t n_obj;
8082
int64_t occupied_byte;

libCacheSim/include/libCacheSim/reader.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ typedef struct {
4545
int32_t time_field;
4646
int32_t obj_id_field;
4747
int32_t obj_size_field;
48+
int32_t obj_cost_field;
4849
int32_t op_field;
4950
int32_t ttl_field;
5051
int32_t cnt_field;

libCacheSim/include/libCacheSim/request.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ typedef struct request {
3232

3333
int64_t obj_size;
3434

35+
int64_t obj_cost;
36+
3537
int32_t ttl;
3638

3739
req_op_e op;
@@ -79,6 +81,7 @@ static inline request_t *new_request(void) {
7981
request_t *req = my_malloc(request_t);
8082
memset(req, 0, sizeof(request_t));
8183
req->obj_size = 1;
84+
req->obj_cost = 1;
8285
req->op = OP_NOP;
8386
req->valid = true;
8487
req->obj_id = 0;
@@ -118,14 +121,17 @@ static inline void free_request(request_t *req) { my_free(request_t, req); }
118121
static inline void print_request(const request_t *req) {
119122
#ifdef SUPPORT_TTL
120123
LOGGING(DEBUG_LEVEL,
121-
"req clock_time %lu, id %llu, size %ld, ttl %ld, op %s, valid %d\n",
124+
"req clock_time %lu, id %llu, size %ld, cost %ld, ttl %ld, op %s, "
125+
"valid %d\n",
122126
(unsigned long)req->clock_time, (unsigned long long)req->obj_id,
123-
(long)req->obj_size, (long)req->ttl, req_op_str[req->op], req->valid);
127+
(long)req->obj_size, (long)req->obj_cost, (long)req->ttl,
128+
req_op_str[req->op], req->valid);
124129
#else
125130
LOGGING(DEBUG_LEVEL,
126-
"req clock_time %lu, id %llu, size %ld, op %s, valid %d\n",
131+
"req clock_time %lu, id %llu, size %ld, cost %ld, op %s, valid %d\n",
127132
(unsigned long)req->clock_time, (unsigned long long)req->obj_id,
128-
(long)req->obj_size, req_op_str[req->op], req->valid);
133+
(long)req->obj_size, (long)req->obj_cost, req_op_str[req->op],
134+
req->valid);
129135
#endif
130136
}
131137

libCacheSim/profiler/simulator.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,13 @@ static void _simulate(gpointer data, gpointer user_data) {
9797
while (req->valid) {
9898
result[idx].n_req++;
9999
result[idx].n_req_byte += req->obj_size;
100+
result[idx].n_req_cost += req->obj_cost;
100101

101102
req->clock_time -= start_ts;
102103
if (local_cache->get(local_cache, req) == false) {
103104
result[idx].n_miss++;
104105
result[idx].n_miss_byte += req->obj_size;
106+
result[idx].n_miss_cost += req->obj_cost;
105107
}
106108
read_one_req(cloned_reader, req);
107109
}

libCacheSim/traceReader/generalReader/binary.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,15 @@ int binaryReader_setup(reader_t *const reader) {
8080
params->obj_size_offset = -1;
8181
}
8282

83+
params->obj_cost_field_idx = reader->init_params.obj_cost_field;
84+
if (params->obj_cost_field_idx > 0) {
85+
params->obj_cost_format = fmt_str[params->obj_cost_field_idx - 1];
86+
params->obj_cost_offset = cal_offset(fmt_str, params->obj_cost_field_idx);
87+
} else {
88+
params->obj_cost_format = '\0';
89+
params->obj_cost_offset = -1;
90+
}
91+
8392
params->op_field_idx = reader->init_params.op_field;
8493
if (params->op_field_idx > 0) {
8594
params->op_format = fmt_str[params->op_field_idx - 1];
@@ -148,6 +157,12 @@ int binaryReader_setup(reader_t *const reader) {
148157
format_to_size(params->obj_size_format),
149158
params->obj_size_offset);
150159
}
160+
if (params->obj_cost_field_idx > 0) {
161+
n += snprintf(output + n, 1024 - n, ", obj_cost_field %d,%d,%d",
162+
params->obj_cost_field_idx,
163+
format_to_size(params->obj_cost_format),
164+
params->obj_cost_offset);
165+
}
151166
if (params->op_field_idx > 0) {
152167
n += snprintf(output + n, 1024 - n, ", op_field %d,%d,%d",
153168
params->op_field_idx, format_to_size(params->op_format),
@@ -226,6 +241,12 @@ int binary_read_one_req(reader_t *reader, request_t *req) {
226241
read_data(start + params->obj_size_offset, params->obj_size_format);
227242
}
228243

244+
/* read object cost */
245+
if (params->obj_cost_field_idx > 0) {
246+
req->obj_cost =
247+
read_data(start + params->obj_cost_offset, params->obj_cost_format);
248+
}
249+
229250
/* read operation */
230251
if (params->op_field_idx > 0) {
231252
req->op = read_data(start + params->op_offset, params->op_format);

libCacheSim/traceReader/generalReader/csv.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,11 @@ static inline void csv_cb1(void *s, size_t len, void *data) {
237237
if (req->obj_size == 0 && end == s) {
238238
WARN("csvReader obj_size is not a number: \"%s\"\n", (char *)s);
239239
}
240+
} else if (csv_params->curr_field_idx == csv_params->obj_cost_field_idx) {
241+
req->obj_cost = (int64_t)strtoll((char *)s, &end, 0);
242+
if (req->obj_cost == 0 && end == s) {
243+
WARN("csvReader obj_cost is not a number: \"%s\"\n", (char *)s);
244+
}
240245
} else if (csv_params->curr_field_idx == csv_params->op_field_idx) {
241246
if (strncasecmp((char *)s, "read", len) == 0) {
242247
req->op = OP_READ;
@@ -298,6 +303,7 @@ void csv_setup_reader(reader_t *const reader) {
298303
csv_params->time_field_idx = init_params->time_field;
299304
csv_params->obj_id_field_idx = init_params->obj_id_field;
300305
csv_params->obj_size_field_idx = init_params->obj_size_field;
306+
csv_params->obj_cost_field_idx = init_params->obj_cost_field;
301307
csv_params->op_field_idx = init_params->op_field;
302308
csv_params->ttl_field_idx = init_params->ttl_field;
303309
csv_params->cnt_field_idx = init_params->cnt_field;

libCacheSim/traceReader/reader.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,8 @@ int read_one_req(reader_t *const reader, request_t *const req) {
258258
reader->n_read_req += 1;
259259
req->hv = 0;
260260
req->ttl = 0;
261+
req->obj_size = 1;
262+
req->obj_cost = 1;
261263
req->valid = true;
262264

263265
switch (reader->trace_type) {
@@ -333,8 +335,14 @@ int read_one_req(reader_t *const reader, request_t *const req) {
333335
req->obj_size = 1;
334336
}
335337

336-
VERBOSE("read one req: time %lu, obj_id %lu, size %lu at offset %zu\n",
337-
req->clock_time, req->obj_id, req->obj_size, offset_before_read);
338+
if (reader->init_params.obj_cost_field <= 0) {
339+
req->obj_cost = 1;
340+
}
341+
342+
VERBOSE(
343+
"read one req: time %lu, obj_id %lu, size %lu, cost %lu at offset %zu\n",
344+
req->clock_time, req->obj_id, req->obj_size, req->obj_cost,
345+
offset_before_read);
338346

339347
return status;
340348
}

0 commit comments

Comments
 (0)