ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
policy_scanresist.c
Go to the documentation of this file.
1
27#include "cache_bench.h"
28#include "ra8_attributes.h"
29
30/* ------------------------------------------------------------------ SLRU -- */
31
33typedef enum : uint8_t {
37
52typedef enum : uint32_t {
57
59typedef struct {
60 int32_t* prev;
61 int32_t* next;
62 int32_t pb_head;
63 int32_t pb_tail;
64 int32_t pt_head;
65 int32_t pt_tail;
66 uint32_t pt_count;
67 uint32_t pt_cap;
68} slru_t;
69
92static void internal_slru_unlink(slru_t* l, int32_t f, int32_t* head, int32_t* tail)
93{
94 if (l->prev[f] != -1) {
95 l->next[l->prev[f]] = l->next[f];
96 } else if (*head == f) {
97 *head = l->next[f];
98 }
99 if (l->next[f] != -1) {
100 l->prev[l->next[f]] = l->prev[f];
101 } else if (*tail == f) {
102 *tail = l->prev[f];
103 }
104}
105
127static void internal_slru_push_head(slru_t* l, int32_t f, int32_t* head, int32_t* tail)
128{
129 l->prev[f] = -1;
130 l->next[f] = *head;
131 if (*head != -1) {
132 l->prev[*head] = f;
133 }
134 *head = f;
135 if (*tail == -1) {
136 *tail = f;
137 }
138}
139
165{
166 const size_t required = sizeof(slru_t) + ((size_t)c->capacity * 2U * sizeof(int32_t));
167 if ((c->policy_workspace == nullptr) || (c->policy_workspace_bytes < required)) {
168 return 1;
169 }
171 l->prev = (int32_t*)&l[1];
172 l->next = &l->prev[c->capacity];
173 l->pb_head = -1;
174 l->pb_tail = -1;
175 l->pt_head = -1;
176 l->pt_tail = -1;
177 l->pt_cap = (c->capacity * (uint32_t)k_slru_protected_pct) / (uint32_t)k_slru_pct_full_scale;
178 c->policy_data = l;
179 return 0;
180}
181
200{
201 c->policy_data = nullptr;
202}
203
223static void internal_slru_insert(cb_cache_t* c, uint32_t frame)
224{
225 slru_t* l = (slru_t*)c->policy_data;
226 c->frames[frame].meta[0] = (uint8_t)k_slru_probation;
227 internal_slru_push_head(l, (int32_t)frame, &l->pb_head, &l->pb_tail);
228}
229
251static void internal_slru_access(cb_cache_t* c, uint32_t frame)
252{
253 slru_t* l = (slru_t*)c->policy_data;
254 const int32_t f = (int32_t)frame;
255 if (c->frames[frame].meta[0] == (uint8_t)k_slru_protected) {
256 internal_slru_unlink(l, f, &l->pt_head, &l->pt_tail);
258 return;
259 }
260 /* Promote probationary -> protected; demote protected LRU if over cap. */
261 internal_slru_unlink(l, f, &l->pb_head, &l->pb_tail);
262 if ((l->pt_cap > 0U) && (l->pt_count == l->pt_cap)) {
263 const int32_t d = l->pt_tail;
264 internal_slru_unlink(l, d, &l->pt_head, &l->pt_tail);
265 c->frames[d].meta[0] = (uint8_t)k_slru_probation;
267 l->pt_count--;
268 }
269 c->frames[frame].meta[0] = (uint8_t)k_slru_protected;
271 l->pt_count++;
272}
273
297static uint32_t internal_slru_victim(cb_cache_t* c, uint32_t* scanned)
298{
299 slru_t* l = (slru_t*)c->policy_data;
300 *scanned = 1U;
301 if (l->pb_tail != -1) {
302 const int32_t f = l->pb_tail;
303 internal_slru_unlink(l, f, &l->pb_head, &l->pb_tail);
304 return (uint32_t)f;
305 }
306 const int32_t f = l->pt_tail;
307 internal_slru_unlink(l, f, &l->pt_head, &l->pt_tail);
308 l->pt_count--;
309 return (uint32_t)f;
310}
311
313 .name = "SLRU",
314 .meta_bytes = (size_t)k_slru_meta_bytes,
315 .state_base_bytes = sizeof(slru_t),
316 .state_frame_bytes = 2U * sizeof(int32_t),
317 .init = internal_slru_init,
318 .deinit = internal_slru_deinit,
319 .on_access = internal_slru_access,
320 .on_insert = internal_slru_insert,
321 .pick_victim = internal_slru_victim,
322};
323
324/* ----------------------------------------------------------------- SRRIP -- */
325
327typedef enum : uint8_t {
332
357{
358 uint32_t* hand = (uint32_t*)c->policy_workspace;
359 c->policy_data = hand;
360 return (hand == nullptr) ? 1 : 0;
361}
362
379{
380 c->policy_data = nullptr;
381}
382
401static void internal_srrip_insert(cb_cache_t* c, uint32_t frame)
402{
403 c->frames[frame].meta[0] = (uint8_t)k_rrip_long;
404}
405
424static void internal_srrip_access(cb_cache_t* c, uint32_t frame)
425{
426 c->frames[frame].meta[0] = (uint8_t)k_rrip_near;
427}
428
451static uint32_t internal_srrip_victim(cb_cache_t* c, uint32_t* scanned)
452{
453 uint32_t* hand = (uint32_t*)c->policy_data;
454 uint32_t seen = 0U;
455 for (;;) {
456 const uint32_t f = *hand;
457 *hand = (*hand + 1U) % c->capacity;
458 seen++;
459 if (c->frames[f].meta[0] == (uint8_t)k_rrip_max) {
460 *scanned = seen;
461 return f;
462 }
463 /* Age toward the max so a victim is guaranteed within two ring passes. */
464 if (c->frames[f].meta[0] < (uint8_t)k_rrip_max) {
465 c->frames[f].meta[0]++;
466 }
467 }
468}
469
471 .name = "SRRIP",
472 .meta_bytes = 1U,
473 .state_base_bytes = sizeof(uint32_t),
474 .state_frame_bytes = 0U,
475 .init = internal_srrip_init,
476 .deinit = internal_srrip_deinit,
477 .on_access = internal_srrip_access,
478 .on_insert = internal_srrip_insert,
479 .pick_victim = internal_srrip_victim,
480};
Eviction-policy comparison harness for the #147 memory-hierarchy decision record: the DIP seam every ...
const cache_policy_t g_cb_policy_srrip
SRRIP: the 2-bit re-reference-interval candidate (src/policy_scanresist.c).
const cache_policy_t g_cb_policy_slru
Segmented-LRU: the scan-resistant candidate (src/policy_scanresist.c).
static void internal_slru_access(cb_cache_t *c, uint32_t frame)
SLRU hit hook: promote or refresh frame on re-reference.
static int internal_slru_init(cb_cache_t *c)
Bind SLRU state: two LRU segments over shared frame arrays.
slru_dim_t
Protected-segment share of the cache, in percent, plus associated scaling and metadata constants.
@ k_slru_protected_pct
Protected-segment target, percent of capacity.
@ k_slru_pct_full_scale
Divisor for percent-to-frame-count conversion.
@ k_slru_meta_bytes
Per-frame metadata: 1 B tag + 8 B list indices.
static void internal_slru_unlink(slru_t *l, int32_t f, int32_t *head, int32_t *tail)
Detach f from the list whose head/tail pointers are given.
static uint32_t internal_srrip_victim(cb_cache_t *c, uint32_t *scanned)
Choose the SRRIP victim by aging RRPVs to the maximum.
slru_seg_t
Per-frame segment tag stored in frame meta[0].
@ k_slru_protected
Frame is in the protected segment.
@ k_slru_probation
Frame is in the probationary segment.
static uint32_t internal_slru_victim(cb_cache_t *c, uint32_t *scanned)
Choose the SLRU victim: probationary LRU first, else protected LRU.
rrip_rrpv_t
RRIP re-reference prediction values (2-bit).
@ k_rrip_max
Furthest – the eviction candidate.
@ k_rrip_long
Distant re-reference (fresh insert).
@ k_rrip_near
Immediate re-reference (just hit).
static void internal_slru_push_head(slru_t *l, int32_t f, int32_t *head, int32_t *tail)
Push f to the MRU head of the segment.
static void internal_srrip_deinit(cb_cache_t *c)
Release SRRIP state (the sweep hand).
static int internal_srrip_init(cb_cache_t *c)
Bind SRRIP state: a sweep hand over the frame ring.
static void internal_srrip_access(cb_cache_t *c, uint32_t frame)
SRRIP hit hook: predict an immediate re-reference for frame.
static void internal_slru_insert(cb_cache_t *c, uint32_t frame)
SLRU insert hook: admit a fresh frame to the probationary segment.
static void internal_srrip_insert(cb_cache_t *c, uint32_t frame)
SRRIP insert hook: predict a distant re-reference for frame.
static void internal_slru_deinit(cb_cache_t *c)
Release SLRU state (control block + shared index arrays).
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
static void internal_slru_access(ra8_keycache_t *kc, int32_t f)
SLRU re-reference: promote / refresh cell f on a hit.
The replacement-policy DIP seam (the eventual firmware Layer-2 seam).
Definition cache_bench.h:75
The fixed-capacity frame cache a policy manages.
Definition cache_bench.h:50
cb_frame_t * frames
capacity frame slots.
Definition cache_bench.h:51
size_t policy_workspace_bytes
Bytes available at the storage.
Definition cache_bench.h:55
void * policy_data
Policy-private state (rings, stacks, sketch).
Definition cache_bench.h:53
uint32_t capacity
Number of frame slots (the RAM budget knob).
Definition cache_bench.h:52
void * policy_workspace
Caller-provided policy-state storage.
Definition cache_bench.h:54
uint8_t meta[16]
Per-policy scratch (ref bits, RRPV, list links).
Definition cache_bench.h:40
Two LRU segments threaded through shared prev/next frame arrays.
int32_t * next
next[f] toward LRU within the frame's segment.
int32_t pb_head
Probationary MRU, or -1.
uint32_t pt_cap
Protected-segment capacity.
int32_t * prev
prev[f] toward MRU within the frame's segment.
int32_t pb_tail
Probationary LRU (first evicted), or -1.
int32_t pt_head
Protected MRU, or -1.
int32_t pt_tail
Protected LRU, or -1.
uint32_t pt_count
Frames currently in the protected segment.