-
Notifications
You must be signed in to change notification settings - Fork 0
/
cache.hpp
158 lines (149 loc) · 4.28 KB
/
cache.hpp
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#ifndef _cache_h
#define _cache_h
#include <iostream>
#include <vector>
#include <map>
#include <cmath>
#include <limits.h>
using namespace std;
#define nway 1 //n way associative , 1 for direct map
#define bl_size 32 //in bytes
#define ca_size 16 //in KBs
/*
1) LRU POLICY: Since lru has been declared as an int it has 32 bits , hence whenever valur of lru reaches INT_MAX the lru of the entire set is changed to zero
2) WRITEBACK: whenever a block with dirty bit 1 is being evicted , it will be counted as a writeback
3) the default has been set to direct , changes can be made for any kind of cache desired
*/
class Block{
int blck[bl_size/4]; //array of ints
int tag;
bool dirty;
int lru;
bool valid;
public:
Block();
friend class CacheSet;
friend class Cache;
};
Block::Block(){
for(int i=0 ; i<bl_size/4 ; i++) blck[i] = 0;
valid = false;
dirty = false;
lru = 0;
}
class CacheSet{
Block Set[nway]; //array of blocks
friend class Cache;
};
class Cache{
CacheSet C[1024*ca_size/(bl_size*nway)]; //array of Sets
int CacheHit;
int CacheMiss;
int WriteBack;
public:
Cache();
int Cread(int);
void Cwrite(int);
int getMisses();
int getHits();
int getWB();
};
int Cache::getMisses(){return CacheMiss;}
int Cache::getHits(){return CacheHit;}
int Cache::getWB(){return WriteBack;}
Cache::Cache(){
CacheHit = 0;
CacheMiss = 0;
WriteBack = 0;
}
int Cache::Cread(int addr){
int off_b = (int)log2((double)bl_size);
int in_b = (int)log2((double)1024*ca_size/(bl_size*nway));
int t_b = 32-in_b-off_b;
unsigned int offset = ((addr << (32-off_b-1))&0x7fffffff) >> (32-off_b-1) ;
unsigned int index = ((addr << t_b-1)&0x7fffffff) >> (32-in_b-1);
unsigned int _tag = ((addr >> 1)&0x7fffffff) >> (32-t_b-1);
int flag=-1;
for(int i=0 ; i<nway ; i++){
if( C[index].Set[i].valid){
if( C[index].Set[i].tag == _tag ){
if( C[index].Set[i].lru == INT_MAX -1){
for(int k=0 ; k<nway ; k++)C[index].Set[k].lru = 0;
}
CacheHit++;C[index].Set[i].lru++;return C[index].Set[i].blck[offset/4];
}
}else if(flag==-1)flag=i;
}
CacheMiss++;
if( flag!=-1){
C[index].Set[flag].tag = _tag;
C[index].Set[flag].valid = true;
if( C[index].Set[flag].lru == INT_MAX -1){
for(int k=0 ; k<nway ; k++)C[index].Set[k].lru = 0;
}
C[index].Set[flag].lru++;
return C[index].Set[flag].blck[offset/4];
}
else{
int minlru=C[index].Set[0].lru , minindex=0;
for(int i=1 ; i<nway ; i++){
if( minlru > C[index].Set[i].lru ){minlru = C[index].Set[i].lru;minindex = i;}
}
if(C[index].Set[minindex].dirty == true )WriteBack++;
C[index].Set[minindex].tag = _tag;
C[index].Set[minindex].valid = true;
if( C[index].Set[minindex].lru == INT_MAX -1){
for(int k=0 ; k<nway ; k++)C[index].Set[k].lru = 0;
}
C[index].Set[minindex].lru++;
C[index].Set[minindex].dirty = false;
return C[index].Set[minindex].blck[offset/4];
}
return 0;
}
void Cache::Cwrite(int addr){
int off_b = (int)log2((double)bl_size);
int in_b = (int)log2((double)1024*ca_size/(bl_size*nway));
int t_b = 32-in_b-off_b;
unsigned int offset = ((addr << (32-off_b-1))&0x7fffffff) >> (32-off_b-1) ;
unsigned int index = ((addr << t_b-1)&0x7fffffff) >> (32-in_b-1);
unsigned int _tag = ((addr >> 1)&0x7fffffff) >> (32-t_b-1);
int flag=-1;
for(int i=0 ; i<nway ; i++){
if( C[index].Set[i].valid){
if( C[index].Set[i].tag == _tag ){
if( C[index].Set[i].lru == INT_MAX -1){
for(int k=0 ; k<nway ; k++)C[index].Set[k].lru = 0;
}
CacheHit++;C[index].Set[i].lru++; C[index].Set[i].dirty = true;return;
}
}else if(flag==-1)flag=i;
}
CacheMiss++;
if( flag!=-1){
C[index].Set[flag].tag = _tag;
C[index].Set[flag].valid = true;
if( C[index].Set[flag].lru == INT_MAX -1){
for(int k=0 ; k<nway ; k++)C[index].Set[k].lru = 0;
}
C[index].Set[flag].lru++;
C[index].Set[flag].dirty = true;
return;
}
else{
int minlru=C[index].Set[0].lru , minindex=0;
for(int i=1 ; i<nway ; i++){
if( minlru > C[index].Set[i].lru )minlru = C[index].Set[i].lru;minindex = i;
}
if(C[index].Set[minindex].dirty == true )WriteBack++;
C[index].Set[minindex].tag = _tag;
C[index].Set[minindex].valid = true;
if( C[index].Set[minindex].lru == INT_MAX -1){
for(int k=0 ; k<nway ; k++)C[index].Set[k].lru = 0;
}
C[index].Set[minindex].lru++;
C[index].Set[minindex].dirty = true;
return;
}
}
#endif