├── .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 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 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 --------------------------------------------------------------------------------