-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcache_simulator.py
More file actions
124 lines (77 loc) · 2.67 KB
/
cache_simulator.py
File metadata and controls
124 lines (77 loc) · 2.67 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
'''
Author: Lucas Parzych
LICENSE: MIT
SOURCE: https://github.com/L-u-k-e/Cache-Simulator
'''
import sys
import argparse
arg_parser = argparse.ArgumentParser(
description='Simulates a configurable set-accociative cache on \
a provided trace of memory accesses. '
)
arg_parser.add_argument('--slots',
type=int, required=True,
help='number of slots in the cache (top level)'
)
arg_parser.add_argument('--sets',
type=int, required=True,
help='number of sets in each slot (middle level)'
)
arg_parser.add_argument('--addr',
type=int, required=True,
help='number of addresses in each set (bottom level)'
)
arg_parser.add_argument('--file',
type=str, required=True,
help='name of the trace file to run the simulation on'
)
args = arg_parser.parse_args()
def main():
lines = readlines(args.file)
memory_accesses = parseTraceInfo(lines)
cache = [[{'tag': None, 'LRU': 0} for x in range(args.sets)] for y in range(args.slots)]
misses = { 'total': 0, 'instruction': 0, 'data': 0 }
for entry in memory_accesses:
slot = cache[entry['slot']]
match = None
for set in slot:
if set['tag'] != entry['tag']:
set['LRU'] += 1
else:
set['LRU'] = 0
match = set
if not match:
misses[entry['type']] += 1
evict_me = max(slot, key = lambda _set: _set['LRU'])
evict_me['tag'] = entry['tag']
evict_me['LRU'] = 0
misses['total'] = misses['instruction'] + misses['data']
number_of_accesses = len(memory_accesses)
for key, value in misses.items():
print("{0} : {1} / {2}".format(key, value, number_of_accesses))
def parseTraceInfo(lines):
#Figure out how many bits we need to reference each level of the cache.
a = vars(args).items()
bit_lengths = { k: len(bin(v-1)[2:]) for k, v in a if k != 'file' }
#Get the starting positions of the slot/offset portions of the address
offset_start = -bit_lengths['addr']
slot_start = -(bit_lengths['slots'] + bit_lengths['addr'])
#Extract useful info from each trace entry.
#I won't actually be using all of this info.
def mappingFunc(line):
parts = line.split()
result = {}
a = bin(int(parts[0], 16))[2:]
result['address'] = a
result['offset'] = int(a[offset_start:], 2)
result['slot'] = int(a[slot_start:offset_start], 2)
result['tag'] = int(a[:slot_start])
result['type'] = 'instruction' if parts[1] == 'I' else 'data'
return result
return list(map(mappingFunc, lines))
def readlines(filename):
try:
return [ line.strip() for line in open(filename) ]
except:
sys.exit('Error: The provided filename "{0}" does not exist in this directory.'.format(filename))
main()