diff --git a/main.py b/main.py index 5857eeba68baaa0c2975a1ddf81c7a3236bbc597..f18536ca0e2395f3ba68165ad18d685096359d5a 100644 --- a/main.py +++ b/main.py @@ -68,8 +68,7 @@ class CacheSimulator(): self.B = int(math.pow(2, self.b)) self.m = self.E * self.S # self.M = int(math.pow(2, self.m)) - self.M = int(math.pow(2, 8)) - # self.M = int(math.pow(2, 64)) + self.M = int(math.pow(2, 64)) # self.debug_print() @@ -115,12 +114,16 @@ class CacheSimulator(): self.hits = 0 self.misses = 0 self.evictions = 0 + self.line = 0 # Open file to read in values. with open(file_name) as file: # Read in line. for line in file: - self.handle_line(line) + self.line += 1 + if line.strip() != '': + # print('line: {0} {1}'.format(self.line, line)) + self.handle_line(line) # self.print_cache() # print('\n') @@ -144,9 +147,33 @@ class CacheSimulator(): # Not an instruction load. Keep processing. Start by parsing line info. parsed_data = {} - address = int(split_line[2], 16) + try: + # Try parsing as hex. + address = int(split_line[2], 16) + except ValueError: + # Invalid address. Attempt to correct bad values. + address = '' + for character in split_line[2]: + # Check if int value of character is greater than f. + if ord(character.lower()) > 102: + address += 'f' + else: + # Not a value less than "f". Attempt to_lower, I guess? + address += character.lower() + + # Attempt again. On error, assume invalid and skip line. + try: + address = int(address, 16) + except ValueError: + return + parsed_data['address'] = address - parsed_data['value_size'] = int(split_line[3]) + + # Attempt to read size value. On error, assume invalid and skip line. + try: + parsed_data['value_size'] = int(split_line[3], 16) - 1 + except ValueError: + return # Get mask values. block_mask = self.B - 1 @@ -171,30 +198,35 @@ class CacheSimulator(): # Check which of 3 operations apply. if split_line[1] == 'L': # Is load. - self.process_load(line, parsed_data, main_bool) + self.process_line(line, parsed_data, main_bool) elif split_line[1] == 'S': # Is store. - self.process_store(line, parsed_data, main_bool) + self.process_line(line, parsed_data, main_bool) elif split_line[1] == 'M': # Load then store. - load_result = self.process_load(line, parsed_data, False) - store_result = self.process_store(line, parsed_data, False) + load_result = self.process_line(line, parsed_data, False) + store_result = self.process_line(line, parsed_data, False) # Check if this is an instruction directly from file. - if main_bool and self.verbose: + if main_bool: # Is instruction from file. Print data. if load_result == 0 and store_result == 0: - print('{0} hit hit'.format(line)) + if self.verbose: + print('{0} hit hit Decimal Format: {1}'.format(line, parsed_data['address'])) + self.hits += 2 elif load_result == 1 and store_result == 0: - print('{0} miss hit'.format(line)) + if self.verbose: + print('{0} miss hit Decimal Format: {1}'.format(line, parsed_data['address'])) + self.misses += 1 + self.hits += 1 elif load_result == 2 and store_result == 0: - print('{0} miss eviction hit'.format(line)) - elif load_result == 1 and store_result == 1: - print('{0} miss miss'.format(line)) - else: - print('{0} miss eviction miss'.format(line)) + if self.verbose: + print('{0} miss eviction hit Decimal Format: {1}'.format(line, parsed_data['address'])) + self.misses += 1 + self.evictions += 1 + self.hits += 1 else: # Unknown operation. @@ -211,35 +243,7 @@ class CacheSimulator(): print(' Line {0}: {1}'.format(line_index, self.cache[set_index][line_index])) print('') - def process_load(self, line, parsed_data, main_bool): - """ - Handle load instruction. Always misses? - :param line: Original line read in. - :param parsed_data: Data parsed from line. - :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. - :return: 1 for unconditional miss? - """ - set = parsed_data['set'] - - # Compare against the all entries in the cache for match. - for index in range(len(self.cache[set])): - # Check if match. - if self.cache[set][index]['valid'] is True and self.cache[set][index]['tag'] == parsed_data['tag']: - # Match found. - self.process_miss(line, parsed_data, index, main_bool) - return 1 - - # If we got this far, then no match was found. Get least recently used index. - try: - index = self.access_log[set][0] - except IndexError: - # Set has not been accessed yet. Use first index. - index = 0 - self.process_miss(line, parsed_data, index, main_bool) - return 1 - - def process_store(self, line, parsed_data, main_bool): + def process_line(self, line, parsed_data, main_bool): """ Handle store instruction. Works as described in class video. :param line: Original line read in. @@ -283,7 +287,7 @@ class CacheSimulator(): # Print if verbose flag set. if self.verbose: - print('{0} hit'.format(line)) + print('{0} hit Decimal Format: {1}'.format(line, parsed_data['address'])) self.update_access_log(parsed_data['set'], index) @@ -302,7 +306,7 @@ class CacheSimulator(): # Print if verbose flag set. if self.verbose: - print('{0} miss'.format(line)) + print('{0} miss Decimal Format: {1}'.format(line, parsed_data['address'])) # Pull out relevant data from passed dict. address = parsed_data['address'] @@ -355,7 +359,7 @@ class CacheSimulator(): # Print if verbose flag set. if self.verbose: - print('{0} miss eviction'.format(line)) + print('{0} miss eviction Decimal Format: {1}'.format(line, parsed_data['address'])) # Pull out relevant data from passed dict. address = parsed_data['address'] @@ -406,7 +410,7 @@ class CacheSimulator(): if __name__ == '__main__': - print('Starting program.') + # print('Starting program.') # Define our argparser and get command line args. parser = argparse.ArgumentParser(description='Cache Simulator') @@ -420,4 +424,4 @@ if __name__ == '__main__': # If args parsed properly, run program main. CacheSimulator().main(int(args.set_count), int(args.line_count), int(args.block_size), args.file_name, args.verbose) - print('Terminating program.') + # print('Terminating program.')