├── .gitattributes
├── .idea
├── .gitignore
├── cache-simulator.iml
├── inspectionProfiles
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
└── vcs.xml
├── README.md
├── inputs.zip
├── main.py
└── پروژه Cache.pdf
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /workspace.xml
3 |
--------------------------------------------------------------------------------
/.idea/cache-simulator.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # cache-simulator
2 | a python program for simulating cache memory
3 | Amirkabir computer architecture course - Dr Farbeh - Spring 2020
4 |
--------------------------------------------------------------------------------
/inputs.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elhamrazi/cache-simulator/5288db8a1247a71f3b3e6e0e547c8cb9fd2bde5e/inputs.zip
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | import math
2 |
3 |
4 | def get_address(address):
5 | total = 0
6 | t = len(address) - 1
7 | for i in address:
8 | total += int(i, 16) * math.pow(16, t)
9 | t = t - 1
10 | return int(total)
11 |
12 |
13 | def output1(a, size, asc, bs, wp, ap):
14 | print("***CACHE SETTINGS***")
15 | if a == '0':
16 | print("Unified I- D-cache")
17 | print("Size:", size)
18 |
19 | else:
20 | print("Split I- D-cache")
21 | print("I-cache size:", int(size[0]))
22 | print("D-cache size:", int(size[2]))
23 | print("Associativity:", asc)
24 | print("Block size:", bs)
25 | if wp == 'wb':
26 | print("Write policy: WRITE BACK")
27 | else:
28 | print("Write policy: WRITE THROUGH")
29 | if ap == "wa":
30 | print("Allocation policy: WRITE ALLOCATE")
31 | else:
32 | print("Allocation policy: WRITE NO ALLOCATE")
33 | print()
34 |
35 |
36 | def output2(acs, miss, replace, iacs, imiss, ireplace, word, copies, wt, wa):
37 | print("***CACHE STATISTICS***")
38 | print("INSTRUCTIONS")
39 | print("accesses:", iacs)
40 | print("misses:", imiss)
41 | if iacs != 0:
42 | i_miss_rate = round((imiss/iacs), 4)
43 | print("miss rate: %.4f" % i_miss_rate, "(hit rate %.4f)" % (1 - i_miss_rate))
44 | if iacs == 0:
45 | print("miss rate: 0.0000 (hit rate 0.0000)")
46 | print("replace:", ireplace)
47 | print("DATA")
48 | print("accesses:", acs)
49 | print("misses:", miss)
50 | if acs != 0:
51 | d_miss_rate = round((miss/acs), 4)
52 | print("miss rate: %.4f" % d_miss_rate, "(hit rate %.4f)" % (1 - d_miss_rate))
53 | else:
54 | print("miss rate:", 0.0000, "(hit rate 0.0000)")
55 | # print("miss rate: %.4f" % d_miss_rate, "(hit rate %.4f)" % (1 - d_miss_rate))
56 | print("replace:", replace)
57 | print("TRAFFIC (in words)")
58 | if writing_policy == 'wb' and allocation == 'wa':
59 | print("demand fetch:", int((imiss + miss) * word), "\ncopies back:", int(word * copies))
60 | if writing_policy == 'wt':
61 | print("demand fetch:", int((imiss + miss - wa) * word), "\ncopies back:", wt)
62 | if allocation == 'nw' and writing_policy == 'wb':
63 | print("demand fetch:", int((imiss + miss - wa) * word), "\ncopies back:", wa + int(copies * word))
64 |
65 |
66 | def creating_cache(w, h):
67 | c = [['x' for x in range(w)] for y in range(h)]
68 | return c
69 |
70 |
71 | def check_lru(lru, tag):
72 | for i in lru:
73 | if tag in i:
74 | return True
75 | return False
76 |
77 |
78 | def unified_cache(info, c_size, associativity_no):
79 | i_miss = 0
80 | i_hit = 0
81 | d_hit = 0
82 | d_miss = 0
83 | i_replace = 0
84 | d_replace = 0
85 | copy_back = 0
86 | wt = 0
87 | wa = 0
88 | nw = 0
89 | blocksize = int(info[0])
90 | words = blocksize / 4
91 | set_no = int(c_size / (blocksize * associativity_no))
92 | # cache = creating_cache(associativity_no, set_no)
93 | # print(*cache)
94 | lru = []
95 | for k in range(set_no):
96 | temp = []
97 | lru.append(temp)
98 | inp = input()
99 | while inp != "":
100 | request = inp.split()
101 | tag = int(get_address(request[1]) / block_size)
102 | set_address = int(tag % set_no)
103 | d = 'c'
104 | if check_lru(lru[set_address], str(tag)):
105 | for i in lru[set_address][:]:
106 | for i in lru[set_address][:]:
107 | if str(tag) in i:
108 | d = i.get(str(tag))
109 | lru[set_address].remove(i)
110 | if request[0] == '1' and writing_policy == 'wb':
111 | d = 'd'
112 | lru[set_address].append({str(tag): d})
113 | # print("hit")
114 | if request[0] == '0' or request[0] == '1':
115 | d_hit += 1
116 | if request[0] == '1' and writing_policy == 'wt':
117 | wt += 1
118 | elif request[0] == '2':
119 | i_hit += 1
120 | # print(lru)
121 | else:
122 | cell = {str(tag): 'c'}
123 | if len(lru[set_address]) < associativity_no:
124 | if request[0] == '1':
125 | if allocation == 'wa':
126 | lru[set_address].append({str(tag): 'd'})
127 | if request[0] == '0' or request[0] == '2':
128 | lru[set_address].append(cell)
129 | # print("miss")
130 | if request[0] == '0' or request[0] == '1':
131 | d_miss += 1
132 | if request[0] == '1':
133 | wt += 1
134 | if allocation == "nw":
135 | wa += 1
136 | elif request[0] == '2':
137 | i_miss += 1
138 | # print(lru)
139 | # print("allocation:", wa)
140 | else:
141 | if allocation != 'nw' or request[0] != '1':
142 | t = lru[set_address].pop(0)
143 | li = list(t.values())
144 | # print(li)
145 | if li[0] == 'd':
146 | copy_back += 1
147 | if request[0] == '1':
148 | if allocation == "wa":
149 | lru[set_address].append({str(tag): 'd'})
150 | if request[0] == '2' or request[0] == '0':
151 | lru[set_address].append(cell)
152 | # print("miss")
153 | if request[0] == '0' or request[0] == '1':
154 | d_miss += 1
155 | d_replace += 1
156 | if request[0] == '1' and writing_policy == 'wt':
157 | wt += 1
158 | if allocation == "nw":
159 | wa += 1
160 | elif request[0] == '2':
161 | i_miss += 1
162 | i_replace += 1
163 | else:
164 | d_miss += 1
165 | wa += 1
166 | wt += 1
167 | # print(lru)
168 | # print("allocation:", wa)
169 | inp = input()
170 | # print(*lru)
171 | # if allocation == 'wa':
172 | for i in lru:
173 | for j in i:
174 | l = list(j.values())
175 | # print(l, l.count('d'))
176 | copy_back += l.count('d')
177 | output1(cache_info[2], cache_size, int(cache_info[4]), block_size, cache_info[6], cache_info[8])
178 | output2(d_hit + d_miss, d_miss, d_replace, i_miss + i_hit, i_miss, i_replace, words, copy_back, wt, wa)
179 |
180 |
181 | def split_cache(info, c_size, associativity_no):
182 | i_miss = 0
183 | i_hit = 0
184 | d_hit = 0
185 | d_miss = 0
186 | i_replace = 0
187 | d_replace = 0
188 | copy_back = 0
189 | wt = 0
190 | wa = 0
191 | blocksize = int(info[0])
192 | words = blocksize / 4
193 | set_no1 = int(int(c_size[2]) / (blocksize * associativity_no))
194 | set_no2 = int(int(c_size[0]) / (blocksize * associativity_no))
195 | lru1 = []
196 | lru2 = []
197 | for k in range(set_no1):
198 | temp = []
199 | lru1.append(temp)
200 | for k in range(set_no2):
201 | temp = []
202 | lru2.append(temp)
203 | inp = input()
204 | while inp != "":
205 | request = inp.split()
206 | if request[0] == '0' or request[0] == '1':
207 | tag = int(get_address(request[1]) / block_size)
208 | set_address = int(tag % set_no1)
209 | d = 'x'
210 | if check_lru(lru1[set_address], str(tag)):
211 | for i in lru1[set_address][:]:
212 | for i in lru1[set_address][:]:
213 | if str(tag) in i:
214 | d = i.get(str(tag))
215 | lru1[set_address].remove(i)
216 | if request[0] == '1' and writing_policy == 'wb':
217 | d = 'd'
218 | lru1[set_address].append({str(tag): d})
219 | # print("hit")
220 | if request[0] == '0' or request[0] == '1':
221 | d_hit += 1
222 | if request[0] == '1':
223 | wt += 1
224 | # print(lru)
225 | else:
226 | cell = {str(tag): 'c'}
227 | if len(lru1[set_address]) < associativity_no:
228 | if request[0] == '1':
229 | if allocation == 'wa':
230 | lru1[set_address].append({str(tag): 'd'})
231 | elif request[0] == '0':
232 | lru1[set_address].append(cell)
233 | # print("miss")
234 | if request[0] == '0' or request[0] == '1':
235 | d_miss += 1
236 | if request[0] == '1':
237 | wt += 1
238 | if allocation == 'nw':
239 | wa += 1
240 | # print(lru)
241 | else:
242 | t = lru1[set_address].pop(0)
243 | li = list(t.values())
244 | if li[0] == 'd':
245 | copy_back += 1
246 | if request[0] == '1':
247 | if allocation == 'wa':
248 | lru1[set_address].append({str(tag): 'd'})
249 | else:
250 | lru1[set_address].append(cell)
251 | # print("miss")
252 | if request[0] == '0' or request[0] == '1':
253 | d_miss += 1
254 | d_replace += 1
255 | if request[0] == '1':
256 | wt += 1
257 | if allocation == 'nw':
258 | wa += 1
259 |
260 | # print(lru)
261 | elif request[0] == '2':
262 | tag = int(get_address(request[1]) / block_size)
263 | set_address = int(tag % set_no2)
264 | if str(tag) in lru2[set_address]:
265 | for i in lru2[set_address][:]:
266 | for i in lru2[set_address][:]:
267 | if i == str(tag):
268 | lru2[set_address].remove(i)
269 | # lru[set_address].remove(str(tag))
270 | lru2[set_address].append(str(tag))
271 | # print("hit")
272 | i_hit += 1
273 | else:
274 | if len(lru2[set_address]) < associativity_no:
275 | lru2[set_address].append(str(tag))
276 | # print("miss1")
277 | i_miss += 1
278 | # print(lru[set_address])
279 | else:
280 | lru2[set_address].pop(0)
281 | lru2[set_address].append(str(tag))
282 | # print("miss2")
283 | i_miss += 1
284 | i_replace += 1
285 | # print(lru[set_address])
286 | inp = input()
287 | for i in lru1:
288 | for j in i:
289 | l = list(j.values())
290 | copy_back += l.count('d')
291 | output1(cache_info[2], c_size, int(cache_info[4]), block_size, cache_info[6], cache_info[8])
292 | output2(d_hit + d_miss, d_miss, d_replace, i_miss + i_hit, i_miss, i_replace, words, copy_back, wt, wa)
293 |
294 |
295 | input1 = input()
296 | cache_size = input()
297 | cache_split = cache_size.split()
298 | cache_info = input1.split()
299 | block_size = int(cache_info[0])
300 | associativity = int(cache_info[4])
301 | writing_policy = cache_info[6]
302 | allocation = cache_info[8]
303 | split = int(cache_info[2])
304 | # if associativity == 1:
305 | # direct_mapped(cache_info, cache_size)
306 | # else:
307 | if len(cache_split) == 1:
308 | unified_cache(cache_info, int(cache_split[0]), associativity)
309 | else:
310 | split_cache(cache_info, cache_split, associativity)
311 |
312 |
313 |
314 |
315 |
316 |
--------------------------------------------------------------------------------
/پروژه Cache.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elhamrazi/cache-simulator/5288db8a1247a71f3b3e6e0e547c8cb9fd2bde5e/پروژه Cache.pdf
--------------------------------------------------------------------------------