-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmarrip.llc_repl
142 lines (119 loc) · 3.95 KB
/
marrip.llc_repl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include "cache.h"
#define maxRRPV 3
#define NUM_POLICY 2
#define MA_HISTORY 50
#define MA_WINDOW 10
#define MARRIP_THRS 15
#define HIT_COUNT_THRS 50
#define MARRIP_THRS_VAL (MARRIP_THRS*MA_HISTORY*MA_WINDOW)/100
uint8_t rrpv[LLC_SET][LLC_WAY],
bip_counter = 0,
rotator = 0,
last_computed_hit_count = 0,
bip_max,
miss_count[NUM_CPUS][MA_HISTORY],
hit_count[NUM_CPUS][MA_HISTORY],
counter[NUM_CPUS],
pointer[NUM_CPUS];
uint8_t get_hit_rate(uint8_t cpu) {
uint8_t hits = 0, miss = 0, total = 0;
for (int i=0; i<MA_HISTORY;i++) {
hits += hit_count[cpu][i];
miss += miss_count[cpu][i];
}
last_computed_hit_count = hits;
total = hits + miss;
return hits*100/total;
}
void CACHE::llc_initialize_replacement() {
bip_max = (MARRIP_THRS*MA_HISTORY*MA_WINDOW)/100;
// set initial values to maxRRPV
for(int i=0; i<LLC_SET; i++) {
for(int j=0; j<LLC_WAY; j++)
rrpv[i][j] = maxRRPV;
}
// set initial hit and miss count to 0 for all CPUs
for (int i=0; i<NUM_CPUS; i++) {
for (int j=0;j<MA_HISTORY;j++) {
hit_count[i][j] = 0;
miss_count[i][j] = 0;
}
pointer[i] = 0;
counter[i] = 0;
}
}
// called on every cache hit and cache fill
void CACHE::llc_update_replacement_state(uint8_t cpu, uint8_t set, uint8_t way, uint64_t full_addr, uint64_t ip, uint64_t victim_addr, uint8_t type, uint8_t hit) {
// update hit/miss counts
uint8_t head = pointer[cpu];
if (hit) {
hit_count[cpu][head]++;
} else {
miss_count[cpu][head]++;
}
// move to next window if current is full and set it to 0.
counter[head]++;
if (counter[head] == MA_WINDOW) {
counter[head] = 0;
uint8_t new_head = (head + 1) % MA_HISTORY;
pointer[cpu] = new_head;
hit_count[cpu][new_head] = 0;
miss_count[cpu][new_head] = 0;
}
if (hit) {
rrpv[set][way] = 0; // for cache hit, SRRIP always promotes a cache line to the MRU position
return;
}
// get hit rate for mode selection
int hit_rate = get_hit_rate(cpu);
// BRRIP
if (hit_rate < MARRIP_THRS) {
rrpv[set][way] = maxRRPV;
// Always set to long reference prediction for writebacks
if (type == WRITEBACK) {
rrpv[set][way] = maxRRPV-1;
}
// if very low cache hits, randomly set to long reference prediction
uint8_t addition_counter = MARRIP_THRS_VAL/(last_computed_hit_count == 0 ? 1 : last_computed_hit_count);
if (addition_counter > 16) addition_counter = 16;
bip_counter += addition_counter;
if (bip_counter >= bip_max) bip_counter = 0;
if (bip_counter == 0) {
rrpv[set][way] = maxRRPV-1;
}
} else {
// SRRIP
rrpv[set][way] = maxRRPV-1;
}
}
// find replacement victim
uint8_t CACHE::llc_find_victim(uint8_t cpu, uint64_t instr_id, uint8_t set, const BLOCK *current_set, uint64_t ip, uint64_t full_addr, uint8_t type) {
// If very low recent cache hits, then randomly select block with maxRRPV.
if (last_computed_hit_count < HIT_COUNT_THRS) {
uint8_t last_rotator = rotator;
// while(1) for edge case
while (1) {
while (++rotator != last_rotator) {
if (rotator == LLC_WAY) rotator = 0;
if (rrpv[set][rotator] == maxRRPV)
return rotator;
}
for (int i=0; i<LLC_WAY; i++)
rrpv[set][i]++;
}
}
// look for the maxRRPV line
while (1) {
for (int i=0; i<LLC_WAY; i++)
if (rrpv[set][i] == maxRRPV)
return i;
for (int i=0; i<LLC_WAY; i++)
rrpv[set][i]++;
}
// WE SHOULD NOT REACH HERE
assert(0);
return 0;
}
// use this function to print out your own stats at the end of simulation
void CACHE::llc_replacement_final_stats() {
}