Advertisement
Guest User

Untitled

a guest
Mar 26th, 2019
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.43 KB | None | 0 0
  1. #!/usr/bin/python
  2.  
  3. import argparse
  4.  
  5. parser = argparse.ArgumentParser(description='Virtual Memory Simulator')
  6. parser.add_argument('-n', required=True, type=int, help='Number of Frames')
  7. parser.add_argument('-a', type=str, required=True,
  8. choices=['opt', 'fifo', 'aging'],
  9. help='Page Replacement Algorithm')
  10. parser.add_argument('-r', type=int, required=False, help='Refresh Amount')
  11. parser.add_argument('filename', help='Trace file', type=str)
  12.  
  13. args = parser.parse_args()
  14. if args.a == 'aging' and not args.r:
  15. print("Refresh [-r] must be specified with aging argument.")
  16. exit(1)
  17.  
  18. # 4KB Page Size means 12 bits will determine (2^20 = 4KB)
  19. PAGE_SIZE_BIT_LENGTH = 12
  20.  
  21. class PageReplacementAlgorithmInterface:
  22. def find_frame(self, frames):
  23. raise NotImplementedError()
  24.  
  25. def on_memory_access(self, frames, frame_no):
  26. raise NotImplementedError()
  27.  
  28. class OptimalReplacementAlgorithm(PageReplacementAlgorithmInterface):
  29. trace_map = {}
  30. def __init__(self, traces):
  31. for i, trace in reversed(list(enumerate(traces))):
  32. page_no = trace.page_no
  33. if page_no not in self.trace_map:
  34. self.trace_map[page_no] = []
  35. self.trace_map[page_no].append(i)
  36.  
  37. def find_frame(self, frames):
  38. max_mem_access_time = -1
  39. maximum_index = -1
  40. page_no = None
  41. for index, page in enumerate(frames):
  42. current_frame_accesses = self.trace_map[page.page_no]
  43. if len(current_frame_accesses) == 0:
  44. current_frame_accesses.append(float('inf'))
  45.  
  46. current_mem_access_time = current_frame_accesses[-1]
  47. if current_mem_access_time == max_mem_access_time:
  48. if frames[maximum_index].dirty_bit and not page.dirty_bit:
  49. # If there is a tie, choose this one if it is not dirty
  50. max_mem_access_time = -1
  51.  
  52. if current_mem_access_time > max_mem_access_time:
  53. max_mem_access_time = current_mem_access_time
  54. maximum_index = index
  55. page_no = page.page_no
  56.  
  57. return maximum_index
  58.  
  59. def on_memory_access(self, frames, frame_no):
  60. page_no = frames[frame_no].page_no
  61. current_frames_accesses = self.trace_map[page_no]
  62. if len(current_frames_accesses) > 0:
  63. self.trace_map[page_no].pop()
  64.  
  65.  
  66.  
  67. class FifoReplacementAlgorithm(PageReplacementAlgorithmInterface):
  68. queue = []
  69.  
  70. def find_frame(self, frames):
  71. frame = self.queue.pop(0)
  72. return frame
  73.  
  74. def on_memory_access(self, frames, frame_no):
  75. if frame_no not in self.queue:
  76. self.queue.append(frame_no)
  77.  
  78. class PageTableEntry:
  79. def __init__(self, page_no, dirty_bit, refresh_bit):
  80. self.page_no = page_no
  81. self.dirty_bit = False
  82. self.refresh_bit = False
  83.  
  84. class PageTable:
  85. page_frame_table = {}
  86. total_memory_accesses = 0
  87. total_page_faults = 0
  88. total_writes_to_disk = 0
  89. new_frames_counter = 0
  90.  
  91. def __init__(self, frames, replacement_algorithm):
  92. self.frames = [None] * frames
  93. self.replacement_algorithm = replacement_algorithm
  94.  
  95. def find_frame(self, page_no):
  96. self.total_memory_accesses += 1
  97. if page_no in self.page_frame_table:
  98. # Hit
  99. return self.page_frame_table[page_no]
  100.  
  101. # Page Fault
  102. self.total_page_faults += 1
  103. if self.new_frames_counter < len(self.frames):
  104. # Page Fault, No Eviction
  105. frame = self.new_frames_counter
  106. self.frames[self.new_frames_counter] = PageTableEntry(page_no, False, False)
  107. self.new_frames_counter += 1
  108. self.page_frame_table[page_no] = frame
  109. return frame
  110.  
  111. # Page Fault, Call Page Replacement Algorithm
  112. frame_no = self.replacement_algorithm.find_frame(self.frames)
  113. del self.page_frame_table[self.frames[frame_no].page_no]
  114.  
  115. if self.frames[frame_no].dirty_bit:
  116. # Evict Dirty So Need to Write to Disk
  117. self.total_writes_to_disk += 1
  118.  
  119. # Evict Clean
  120. self.frames[frame_no] = PageTableEntry(page_no, False, False)
  121. self.page_frame_table[page_no] = frame_no
  122. return frame_no
  123.  
  124.  
  125. def store(self, page_no):
  126. # Find Page and Set Dirty Bit to True
  127. frame_no = self.find_frame(page_no)
  128. self.frames[frame_no].dirty_bit = True
  129. self.replacement_algorithm.on_memory_access(self.frames, frame_no)
  130.  
  131. def load(self, page_no):
  132. frame_no = self.find_frame(page_no)
  133. self.replacement_algorithm.on_memory_access(self.frames, frame_no)
  134.  
  135.  
  136. class MemoryAccess:
  137. def __init__(self, trace):
  138. parts = trace.strip().split()
  139. self.op = parts[0].upper()
  140. logical_address = int(parts[1], 16)
  141. self.page_no = logical_address >> PAGE_SIZE_BIT_LENGTH
  142. # Get bottom 12 bits ( & 0xFFF)
  143. self.offset = logical_address & ((1<<PAGE_SIZE_BIT_LENGTH)-1)
  144. self.cycles = int(parts[2])
  145.  
  146. def __str__(self):
  147. return "{} {} {} {}".format(self.op, self.page_no, self.offset, self.cycles)
  148.  
  149.  
  150. traces = []
  151. with open(args.filename) as file:
  152. for line in file:
  153. traces.append(MemoryAccess(line))
  154.  
  155.  
  156.  
  157. algs = {
  158. "fifo": FifoReplacementAlgorithm(),
  159. "opt": OptimalReplacementAlgorithm(traces)
  160. }
  161.  
  162. page_replacement_algorithm = algs[args.a]
  163. page_table = PageTable(args.n, page_replacement_algorithm)
  164.  
  165. for mem_access in traces:
  166. if mem_access.op == "S":
  167. page_table.store(mem_access.page_no)
  168. else:
  169. page_table.load(mem_access.page_no)
  170.  
  171. def print_statistics(page_table):
  172. print("Algorithm: {}".format(args.a.upper()))
  173. print("Number of frames: {}".format(args.n))
  174. print("Total memory accesses: {}".format(page_table.total_memory_accesses))
  175. print("Total page faults: {}".format(page_table.total_page_faults))
  176. print("Total writes to disk: {}".format(page_table.total_writes_to_disk))
  177.  
  178. print_statistics(page_table)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement