Skip to content
Snippets Groups Projects
Commit 77ede8f6 authored by Brandon Rodriguez's avatar Brandon Rodriguez
Browse files

Split hit/miss/evict logic into separate functions

parent bfc112c5
Branches
No related merge requests found
......@@ -107,11 +107,11 @@ class CacheSimulator():
print('hits:{0} misses:{1} evictions:{2}'.format(self.hits, self.misses, self.evictions))
def handle_line(self, line, main_cache_line=True):
def handle_line(self, line, main_bool=True):
"""
Handles cache simulation for given line instruction.
:param line: Line to handle for.
:param main_cache_line: Bool to indicate if this is an initial cache line read in or a subquery from one.
:param main_bool: Bool to indicate if this is an initial cache line read in or a subquery from one.
Note that only initial cache line read ins will print or update missed/skipped/evicted variables.
"""
split_line = re.split(r'[ ,\n]', line)
......@@ -123,9 +123,11 @@ class CacheSimulator():
else:
line = line.strip()
# Not an instruction load. Keep processing. Start by getting address.
address = int(split_line[2]) % self.M
value_size = int(split_line[3])
# Not an instruction load. Keep processing. Start by parsing line info.
parsed_data = {}
address = int(split_line[2])
parsed_data['address'] = address
parsed_data['value_size'] = int(split_line[3])
# Get mask values.
block_mask = self.B - 1
......@@ -135,94 +137,26 @@ class CacheSimulator():
tag_mask = (self.M - 1) ^ set_mask ^ block_mask
# Use masks to get address chunks.
block = address & block_mask
parsed_data['block'] = address & block_mask
set = (address & set_mask) >> block_offset
parsed_data['set'] = set
tag = (address & tag_mask) >> (block_offset + set_offset)
parsed_data['tag'] = tag
# We have our values. Now compare against the all entries in the cache.
for index in range(len(self.cache[set])):
# Check if match.
if self.cache[set][index]['valid'] == True and self.cache[set][index]['tag'] == tag:
# Match found.
if main_cache_line:
# Is main cache file line. Update hits/misses/evictions.
self.hits += 1
# Print if verbose flag set.
if self.verbose:
print('{0} hit'.format(line))
return
return self.process_hit(line, set, main_bool)
else:
# Not a match. Examine why.
if self.cache[set][index]['valid'] == False:
# Cache location was not set. Cold miss. We can just set and return.
if main_cache_line:
# Is main cache file line. Update hits/misses/evictions.
self.misses += 1
# Print if verbose flag set.
if self.verbose:
print('{0} miss'.format(line))
self.cache[set][index]['valid'] = True
self.cache[set][index]['tag'] = tag
# Set block values that are "loaded" into memory.
lower_offset = int(address / self.B) * self.B
upper_offset = (int(address / self.B) + 1) * self.B
value_offset = address + value_size
self.cache[set][index]['block'] = []
for i in range(self.B):
self.cache[set][index]['block'].append(lower_offset + i)
# Check if size sets address outside of current cache block.
if value_offset >= upper_offset:
# Size sets address outside of current cache block. Update additional blocks as needed.
# Start by getting our new size.
new_size = value_offset - upper_offset
if new_size < 0:
new_size = 0
# Pass our new line data.
new_line = ' L {0},{1}'.format(upper_offset, new_size)
self.handle_line(new_line, main_cache_line=False)
return
return self.process_miss(line, parsed_data, index, main_bool)
# If we made it this far, cache locations were set, but tags did not match. Conflict miss.
if main_cache_line:
# Is main cache file line. Update hits/misses/evictions.
self.misses += 1
self.evictions += 1
# Print if verbose flag set.
if self.verbose:
print('{0} miss eviction'.format(line))
self.cache[set][0]['tag'] = tag
# Set block values that are "loaded" into memory.
lower_offset = int(address / self.B) * self.B
upper_offset = (int(address / self.B) + 1) * self.B
value_offset = address + value_size
self.cache[set][0]['block'] = []
for i in range(self.B):
self.cache[set][0]['block'].append(lower_offset + i)
# Check if size sets address outside of current cache block.
if value_offset >= upper_offset:
# Size sets address outside of current cache block. Update additional blocks as needed.
# Start by getting our new size.
new_size = value_offset - upper_offset
if new_size < 0:
new_size = 0
# Pass our new line data.
new_line = ' L {0},{1}'.format(upper_offset, new_size)
self.handle_line(new_line, main_cache_line=False)
return
return self.process_eviction(line, parsed_data, main_bool)
def print_cache(self):
"""
......@@ -235,6 +169,91 @@ class CacheSimulator():
print(' Line {0}: {1}'.format(line_index, self.cache[set_index][line_index]))
print('')
def process_hit(self, line, parsed_data, main_bool):
if main_bool:
# Is main cache file line. Update hits/misses/evictions.
self.hits += 1
# Print if verbose flag set.
if self.verbose:
print('{0} hit'.format(line))
def process_miss(self, line, parsed_data, index, main_bool):
if main_bool:
# Is main cache file line. Update hits/misses/evictions.
self.misses += 1
# Print if verbose flag set.
if self.verbose:
print('{0} miss'.format(line))
# Pull out relevant data from passed dict.
address = parsed_data['address']
value_size = parsed_data['value_size']
set = parsed_data['set']
tag = parsed_data['tag']
self.cache[set][index]['valid'] = True
self.cache[set][index]['tag'] = tag
# Set block values that are "loaded" into memory.
lower_offset = int(address / self.B) * self.B
upper_offset = (int(address / self.B) + 1) * self.B
value_offset = address + value_size
self.cache[set][index]['block'] = []
for i in range(self.B):
self.cache[set][index]['block'].append(lower_offset + i)
# Check if size sets address outside of current cache block.
if value_offset >= upper_offset:
# Size sets address outside of current cache block. Update additional blocks as needed.
# Start by getting our new size.
new_size = value_offset - upper_offset
if new_size < 0:
new_size = 0
# Pass our new line data.
new_line = ' L {0},{1}'.format(upper_offset, new_size)
self.handle_line(new_line, main_bool=False)
def process_eviction(self, line, parsed_data, main_bool):
if main_bool:
# Is main cache file line. Update hits/misses/evictions.
self.misses += 1
self.evictions += 1
# Print if verbose flag set.
if self.verbose:
print('{0} miss eviction'.format(line))
# Pull out relevant data from passed dict.
address = parsed_data['address']
value_size = parsed_data['value_size']
set = parsed_data['set']
tag = parsed_data['tag']
self.cache[set][0]['tag'] = tag
# Set block values that are "loaded" into memory.
lower_offset = int(address / self.B) * self.B
upper_offset = (int(address / self.B) + 1) * self.B
value_offset = address + value_size
self.cache[set][0]['block'] = []
for i in range(self.B):
self.cache[set][0]['block'].append(lower_offset + i)
# Check if size sets address outside of current cache block.
if value_offset >= upper_offset:
# Size sets address outside of current cache block. Update additional blocks as needed.
# Start by getting our new size.
new_size = value_offset - upper_offset
if new_size < 0:
new_size = 0
# Pass our new line data.
new_line = ' L {0},{1}'.format(upper_offset, new_size)
self.handle_line(new_line, main_bool=False)
if __name__ == '__main__':
print('Starting program.')
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment