Skip to content

Commit c3d754e

Browse files
committed
Add GroupMergeAdaptive2 eviction algorithm and enhance existing algorithms
- Implemented GroupMergeAdaptive2, an activity-driven adaptive group-based eviction algorithm. - Introduced new parameters for group size, active threshold, and retention policy. - Enhanced GroupMergeHead and Sieve algorithms to track additional statistics for object retention and eviction. - Updated cache object structure to include metadata for GroupMergeAdaptive2. - Modified eviction algorithm headers to include new initialization functions for GroupMergeAdaptive2. - Added file handling for tracking retention ratios and object examination statistics in Sieve.
1 parent 52c27fe commit c3d754e

File tree

11 files changed

+1440
-4
lines changed

11 files changed

+1440
-4
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,6 @@ sftp-config.json
2323
# Python wheels
2424
*.whl
2525
2024_google/*
26+
.nfs*
27+
figure/*
28+
results/*

libCacheSim/bin/cachesim/cache_init.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ static inline cache_t *create_cache(const char *trace_path,
5656
{"groupmergehead", GroupMergeHead_init},
5757
{"group-merge-head", GroupMergeHead_init},
5858
{"group_merge_head", GroupMergeHead_init},
59+
{"groupmergeadaptive", GroupMergeAdaptive_init},
60+
{"group-merge-adaptive", GroupMergeAdaptive_init},
61+
{"group_merge_adaptive", GroupMergeAdaptive_init},
62+
{"groupmergeadaptive2", GroupMergeAdaptive2_init},
63+
{"group-merge-adaptive2", GroupMergeAdaptive2_init},
64+
{"group_merge_adaptive2", GroupMergeAdaptive2_init},
5965
{"gdsf", GDSF_init},
6066
{"lhd", LHD_init},
6167
{"lecar", LeCaR_init},

libCacheSim/cache/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ set(eviction_sources_c
6969
eviction/FIFO_Reinsertion.c
7070
eviction/GroupMerge.c
7171
eviction/GroupMergeHead.c
72+
eviction/GroupMergeAdaptive.c
73+
eviction/GroupMergeAdaptive2.c
7274
eviction/S3FIFOv0.c
7375
eviction/S3FIFOd.c
7476
eviction/other/flashProb.c

libCacheSim/cache/eviction/Clock.c

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
extern "C" {
1818
#endif
1919

20-
#define USE_BELADY
21-
// #undef USE_BELADY
20+
// #define USE_BELADY
21+
#undef USE_BELADY
2222

2323
static const char *DEFAULT_PARAMS = "init-freq=0,n-bit-counter=1";
2424

@@ -90,6 +90,23 @@ cache_t *Clock_init(const common_cache_params_t ccache_params,
9090
params->n_bit_counter, params->init_freq);
9191
}
9292

93+
// open tracking file
94+
{
95+
char fname[256];
96+
const char *trace_name = getenv("TRACKING_TRACE_NAME");
97+
if (trace_name)
98+
snprintf(fname, sizeof(fname), "tracking_%s_%s_%lld.csv", trace_name,
99+
cache->cache_name, (long long)cache->cache_size);
100+
else
101+
snprintf(fname, sizeof(fname), "tracking_%s_%lld.csv", cache->cache_name,
102+
(long long)cache->cache_size);
103+
params->tracking_file = fopen(fname, "w");
104+
if (params->tracking_file) {
105+
fprintf(params->tracking_file,
106+
"vtime,n_obj,avg_scan_depth,retention_ratio\n");
107+
}
108+
}
109+
93110
return cache;
94111
}
95112

@@ -99,6 +116,8 @@ cache_t *Clock_init(const common_cache_params_t ccache_params,
99116
* @param cache
100117
*/
101118
static void Clock_free(cache_t *cache) {
119+
Clock_params_t *params = (Clock_params_t *)cache->eviction_params;
120+
if (params->tracking_file) fclose(params->tracking_file);
102121
free(cache->eviction_params);
103122
cache_struct_free(cache);
104123
}
@@ -263,10 +282,33 @@ static void Clock_evict(cache_t *cache, const request_t *req) {
263282
params->n_byte_rewritten += obj_to_evict->obj_size;
264283
move_obj_to_head(&params->q_head, &params->q_tail, obj_to_evict);
265284
obj_to_evict = params->q_tail;
285+
params->n_obj_examined_interval++;
286+
params->n_obj_retained_interval++;
266287
}
267288

289+
params->n_obj_examined_interval++;
290+
params->n_evictions_interval++;
291+
268292
remove_obj_from_list(&params->q_head, &params->q_tail, obj_to_evict);
269293
cache_evict_base(cache, obj_to_evict, true);
294+
295+
if (params->tracking_file &&
296+
cache->n_req - params->last_report_vtime >= 100000) {
297+
double avg_scan = params->n_evictions_interval > 0
298+
? (double)params->n_obj_examined_interval /
299+
params->n_evictions_interval
300+
: 0.0;
301+
double retention = params->n_obj_examined_interval > 0
302+
? (double)params->n_obj_retained_interval /
303+
params->n_obj_examined_interval
304+
: 0.0;
305+
fprintf(params->tracking_file, "%ld,%ld,%.4f,%.4f\n", (long)cache->n_req,
306+
(long)cache->get_n_obj(cache), avg_scan, retention);
307+
params->n_obj_examined_interval = 0;
308+
params->n_obj_retained_interval = 0;
309+
params->n_evictions_interval = 0;
310+
params->last_report_vtime = cache->n_req;
311+
}
270312
}
271313

272314
/**

libCacheSim/cache/eviction/GroupMerge.c

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ typedef struct GroupMerge_params {
5252
int n_objs_to_evict;
5353
int pos_in_metric_list;
5454

55+
int64_t n_obj_inserted;
56+
int64_t n_byte_inserted;
57+
int64_t n_obj_retained;
58+
int64_t n_byte_retained;
59+
5560
int64_t n_obj_rewritten;
5661
int64_t n_byte_rewritten;
5762
} GroupMerge_params_t;
@@ -107,7 +112,9 @@ cache_t *GroupMerge_init(const common_cache_params_t ccache_params,
107112
memset(params, 0, sizeof(GroupMerge_params_t));
108113
cache->eviction_params = params;
109114

110-
params->group_size = 20 * 1024 * 1024; // 20 MiB
115+
// default group_size = cache_size / 1000
116+
params->group_size = (int64_t)ccache_params.cache_size / 1000;
117+
if (params->group_size < 1) params->group_size = 1;
111118
params->n_exam_groups = 4;
112119
params->retain_policy = RETAIN_POLICY_RECENCY;
113120
params->next_to_exam = NULL;
@@ -125,6 +132,20 @@ cache_t *GroupMerge_init(const common_cache_params_t ccache_params,
125132

126133
assert(params->group_size > 0 && params->n_exam_groups >= 2);
127134

135+
// clamp group_size so it cannot exceed a fraction of the cache; otherwise
136+
// each scan covers ~the whole cache while retaining everything, forcing
137+
// batched evictions of 1, which is O(N^2) per pass.
138+
int64_t max_group_size = (int64_t)ccache_params.cache_size /
139+
(int64_t)(params->n_exam_groups * 2);
140+
if (max_group_size < 1) max_group_size = 1;
141+
if (params->group_size > max_group_size) {
142+
WARN("GroupMerge: group-size %ld too large for cache size %lu; "
143+
"clamping to %ld (cache_size / (2*E))\n",
144+
(long)params->group_size, (unsigned long)ccache_params.cache_size,
145+
(long)max_group_size);
146+
params->group_size = max_group_size;
147+
}
148+
128149
snprintf(cache->cache_name, CACHE_NAME_ARRAY_LEN,
129150
"GroupMerge_gs%ld_E%d_%s", (long)params->group_size,
130151
params->n_exam_groups,
@@ -135,6 +156,15 @@ cache_t *GroupMerge_init(const common_cache_params_t ccache_params,
135156

136157
static void GroupMerge_free(cache_t *cache) {
137158
GroupMerge_params_t *params = (GroupMerge_params_t *)cache->eviction_params;
159+
double retain_ratio = params->n_byte_inserted > 0
160+
? (double)params->n_byte_retained / (double)params->n_byte_inserted
161+
: 0.0;
162+
INFO(
163+
"%s: inserted %ld obj / %ld bytes, retained %ld obj / %ld bytes "
164+
"(retained/inserted byte ratio = %.4f)\n",
165+
cache->cache_name, (long)params->n_obj_inserted,
166+
(long)params->n_byte_inserted, (long)params->n_obj_retained,
167+
(long)params->n_byte_retained, retain_ratio);
138168
free(params->metric_list);
139169
my_free(sizeof(GroupMerge_params_t), params);
140170
cache_struct_free(cache);
@@ -170,6 +200,9 @@ static cache_obj_t *GroupMerge_insert(cache_t *cache, const request_t *req) {
170200
cache_obj->GroupMerge.freq = 0;
171201
cache_obj->GroupMerge.last_access_vtime = (int32_t)cache->n_req;
172202

203+
params->n_obj_inserted += 1;
204+
params->n_byte_inserted += cache_obj->obj_size;
205+
173206
return cache_obj;
174207
}
175208

@@ -195,6 +228,8 @@ static void GroupMerge_evict(cache_t *cache, const request_t *req) {
195228
for (int i = params->n_objs_to_evict; i < params->n_objs_in_batch; i++) {
196229
cache_obj_t *retained = params->metric_list[i].cache_obj;
197230
retained->GroupMerge.freq = (retained->GroupMerge.freq + 1) / 2;
231+
params->n_obj_retained += 1;
232+
params->n_byte_retained += retained->obj_size;
198233
}
199234
params->pos_in_metric_list = INT32_MAX;
200235
}
@@ -291,6 +326,8 @@ static void GroupMerge_evict(cache_t *cache, const request_t *req) {
291326
for (int i = params->n_objs_to_evict; i < params->n_objs_in_batch; i++) {
292327
cache_obj_t *retained = params->metric_list[i].cache_obj;
293328
retained->GroupMerge.freq = (retained->GroupMerge.freq + 1) / 2;
329+
params->n_obj_retained += 1;
330+
params->n_byte_retained += retained->obj_size;
294331
}
295332
params->pos_in_metric_list = INT32_MAX;
296333
}

0 commit comments

Comments
 (0)