-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcache.cpp
More file actions
158 lines (127 loc) · 3.47 KB
/
Copy pathcache.cpp
File metadata and controls
158 lines (127 loc) · 3.47 KB
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
#include <iostream>
#include <iomanip>
#include <math.h>
#include <vector>
using namespace std;
#define DBG 1
#define DRAM_SIZE (64*1024*1024)
#define CACHE_SIZE (64*1024)
#define CASHE_LINE_SIZE (16)
#define NO_WAYS (1)
int no_lines = (CACHE_SIZE / CASHE_LINE_SIZE);
int bits_index = log2(no_lines);
int no_byte_offset = log2(CASHE_LINE_SIZE);
// First ---> Validity Bit , Second ----> TAG
vector < vector<pair<int, int>>> set_associative_cache(no_lines, vector< pair<int, int>>(NO_WAYS, { 0,0 }));
enum cacheResType { MISS = 0, HIT = 1 };
/* The following implements a random number generator */
unsigned int m_w = 0xABCCAB99; /* must not be zero, nor 0x464fffff */
unsigned int m_z = 0xDEAD6902; /* must not be zero, nor 0x9068ffff */
unsigned int rand_()
{
m_z = 36969 * (m_z & 65535) + (m_z >> 16);
m_w = 18000 * (m_w & 65535) + (m_w >> 16);
return (m_z << 16) + m_w; /* 32-bit result */
}
struct cache_line
{
int index;
int tag;
};
unsigned int memGenA()
{
static unsigned int addr = 0;
return (addr++) % (DRAM_SIZE);
}
unsigned int memGenB()
{
static unsigned int addr = 0;
return rand_() % (64 * 1024);
}
unsigned int memGenC()
{
static unsigned int a1 = 0, a0 = 0;
a0++;
if (a0 == 512) { a1++; a0 = 0; }
if (a1 == 128) a1 = 0;
return(a1 + a0 * 128);
}
unsigned int memGenD()
{
return rand_() % (16 * 1024);
}
unsigned int memGenE()
{
static unsigned int addr = 0;
return (addr++) % (1024 * 64);
}
unsigned int memGenF()
{
static unsigned int addr = 0;
return (addr += 64) % (64 * 4 * 1024);
}
// Direct Mapped Cache Simulator
cacheResType cacheSimDM(unsigned int addr)
{
// This function accepts the memory address for the memory transaction and
// returns whether it caused a cache miss or a cache hit
cache_line L;
// Exclude offset bits
int temp_addr = addr >> no_byte_offset;
// Get index bits
L.index = temp_addr % (1 << bits_index);
temp_addr /= (1 << bits_index);
// Get tag bits
L.tag = temp_addr;
int i = 0;
for (; i < NO_WAYS; i++)
{
if (set_associative_cache[L.index][i].first)
{
if (set_associative_cache[L.index][i].second == L.tag)
return HIT;
}
else break;
}
// This case means we will replace the fisrt address in the set by the new address
if (i == NO_WAYS)
{
set_associative_cache[L.index][rand() % NO_WAYS].second = L.tag;
}
// This case means that there is still empty place in the set to store the address
else
{
set_associative_cache[L.index][i].first = 1;
set_associative_cache[L.index][i].second = L.tag;
}
return MISS;
}
char* msg[2] = { (char*)"Miss", (char*)"Hit" };
#define NO_OF_Iterations 1000000 // CHange to 1,000,000
int main()
{
float hit = 0;
cacheResType r;
unsigned int addr;
cout << "Cache Simulator\n";
for (int inst = 0; inst < NO_OF_Iterations; inst++)
{
//cin >> addr;
addr = memGenA();
r = cacheSimDM(addr);
if (r == HIT) hit++;
//cout << "0x" << setfill('0') << setw(8) << hex << addr << " (" << msg[r] << ")\n";
}
//cout << "Hit ratio = " << (float)(100.0 * hit / NO_OF_Iterations) << " %" << endl;
// validation --> Uncomment when testing
/*
for(int i=0; i<no_lines; i++){
cout << "index " << i << ": ";
for(int j=0; j<NO_WAYS; j++){
cout<< "v: "<< set_associative_cache[i][j].first << " tag: "<< set_associative_cache[i][j].second << " , ";
}
cout<<endl;
}*/
cout << "Hit ratio = " << (float)(100.0 * hit / NO_OF_Iterations) << " %" << endl;
cout << "Miss ratio = " << 100.0 - (float)(100.0 * hit / NO_OF_Iterations) << " %" << endl;
}