-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSimpleCache.cpp
83 lines (72 loc) · 1.82 KB
/
SimpleCache.cpp
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
#include "SimpleCache.h"
SimpleCache::SimpleCache(int capacity, int blockSize, int ways)
{
Capacity = capacity;
BlockSize = blockSize;
Ways = ways;
Blocks = Capacity / BlockSize;
Sets = Blocks / Ways;
cache = new SimpleCacheline [Blocks];
evicted = new SimpleCacheline;
numAccess = 0;
debug = 0;
}
SimpleCache::~SimpleCache()
{
delete []cache;
delete evicted;
}
int SimpleCache::Read(uint64_t addr)
{
numAccess++;
int set = addr % Sets;
int hit_at = -1;
for (int j = 0; j < Ways; j++)
{
SimpleCacheline * current = cache + set * Ways + j;
if (current->valid && current->tag == addr)
{
current->last_time = numAccess;
hit_at = set * Ways + j;
break;
}
}
if (debug)
printf("read %ld, result = %d\n", addr, hit_at);
return hit_at;
}
int SimpleCache::Write(uint64_t addr)
{
assert(Read(addr) < 0);
numAccess--;
int set = addr % Sets;
uint64_t least_recent_time = cache[set * Ways].last_time;
int replacement = 0;
SimpleCacheline * current;
for (int j = 0; j < Ways; j++)
{
current = cache + set * Ways + j;
if (!current->valid)
{
replacement = j;
break;
}
else if (current->last_time < least_recent_time)
{
replacement = j;
least_recent_time = current->last_time;
}
}
current = cache + set * Ways + replacement;
*evicted = *current;
*current = (SimpleCacheline) {1, addr, numAccess};
if (debug)
{
printf("write %ld, ", addr);
if (evicted->valid)
printf("evicting %ld\n", evicted->tag);
else
printf("no eviction\n");
}
return evicted->valid; // -1 no eviction; -2 evicted some other line
}