《操作系统》的实验代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
7.5 KiB

  1. #! /usr/bin/env python
  2. import sys
  3. from optparse import OptionParser
  4. import random
  5. import math
  6. def hfunc(index):
  7. if index == -1:
  8. return 'MISS'
  9. else:
  10. return 'HIT '
  11. def vfunc(victim):
  12. if victim == -1:
  13. return '-'
  14. else:
  15. return str(victim)
  16. #
  17. # main program
  18. #
  19. parser = OptionParser()
  20. parser.add_option('-a', '--addresses', default='-1', help='a set of comma-separated pages to access; -1 means randomly generate', action='store', type='string', dest='addresses')
  21. parser.add_option('-p', '--policy', default='FIFO', help='replacement policy: FIFO, LRU, OPT, CLOCK', action='store', type='string', dest='policy')
  22. parser.add_option('-b', '--clockbits', default=1, help='for CLOCK policy, how many clock bits to use', action='store', type='int', dest='clockbits')
  23. parser.add_option('-f', '--pageframesize', default='3', help='size of the physical page frame, in pages', action='store', type='string', dest='pageframesize')
  24. parser.add_option('-s', '--seed', default='0', help='random number seed', action='store', type='string', dest='seed')
  25. parser.add_option('-N', '--notrace', default=False, help='do not print out a detailed trace', action='store_true', dest='notrace')
  26. parser.add_option('-c', '--compute', default=False, help='compute answers for me', action='store_true', dest='solve')
  27. (options, args) = parser.parse_args()
  28. print 'ARG addresses', options.addresses
  29. print 'ARG policy', options.policy
  30. print 'ARG clockbits', options.clockbits
  31. print 'ARG pageframesize', options.pageframesize
  32. print 'ARG seed', options.seed
  33. print 'ARG notrace', options.notrace
  34. print ''
  35. addresses = str(options.addresses)
  36. pageframesize = int(options.pageframesize)
  37. seed = int(options.seed)
  38. policy = str(options.policy)
  39. notrace = options.notrace
  40. clockbits = int(options.clockbits)
  41. random.seed(seed)
  42. addrList = []
  43. addrList = addresses.split(',')
  44. if options.solve == False:
  45. print 'Assuming a replacement policy of %s, and a physical page frame of size %d pages,' % (policy, pageframesize)
  46. print 'figure out whether each of the following page references hit or miss'
  47. for n in addrList:
  48. print 'Access: %d Hit/Miss? State of Memory?' % int(n)
  49. print ''
  50. else:
  51. if notrace == False:
  52. print 'Solving...\n'
  53. # init memory structure
  54. count = 0
  55. memory = []
  56. hits = 0
  57. miss = 0
  58. if policy == 'FIFO':
  59. leftStr = 'FirstIn'
  60. riteStr = 'Lastin '
  61. elif policy == 'LRU':
  62. leftStr = 'LRU'
  63. riteStr = 'MRU'
  64. elif policy == 'OPT' or policy == 'CLOCK':
  65. leftStr = 'Left '
  66. riteStr = 'Right'
  67. else:
  68. print 'Policy %s is not yet implemented' % policy
  69. exit(1)
  70. # track reference bits for clock
  71. ref = {}
  72. cdebug = False
  73. # need to generate addresses
  74. addrIndex = 0
  75. for nStr in addrList:
  76. # first, lookup
  77. n = int(nStr)
  78. try:
  79. idx = memory.index(n)
  80. hits = hits + 1
  81. if policy == 'LRU' :
  82. update = memory.remove(n)
  83. memory.append(n) # puts it on MRU side
  84. except:
  85. idx = -1
  86. miss = miss + 1
  87. victim = -1
  88. if idx == -1:
  89. # miss, replace?
  90. # print 'BUG count, pageframesize:', count, pageframesize
  91. if count == pageframesize:
  92. # must replace
  93. if policy == 'FIFO' or policy == 'LRU':
  94. victim = memory.pop(0)
  95. elif policy == 'CLOCK':
  96. if cdebug:
  97. print 'REFERENCE TO PAGE', n
  98. print 'MEMORY ', memory
  99. print 'REF (b)', ref
  100. # hack: for now, do random
  101. # victim = memory.pop(int(random.random() * count))
  102. victim = -1
  103. while victim == -1:
  104. page = memory[int(random.random() * count)]
  105. if cdebug:
  106. print ' scan page:', page, ref[page]
  107. if ref[page] >= 1:
  108. ref[page] -= 1
  109. else:
  110. # this is our victim
  111. victim = page
  112. memory.remove(page)
  113. break
  114. # remove old page's ref count
  115. if page in memory:
  116. assert('BROKEN')
  117. del ref[victim]
  118. if cdebug:
  119. print 'VICTIM', page
  120. print 'LEN', len(memory)
  121. print 'MEM', memory
  122. print 'REF (a)', ref
  123. elif policy == 'OPT':
  124. maxReplace = -1
  125. replaceIdx = -1
  126. replacePage = -1
  127. # print 'OPT: access %d, memory %s' % (n, memory)
  128. # print 'OPT: replace from FUTURE (%s)' % addrList[addrIndex+1:]
  129. for pageIndex in range(0,count):
  130. page = memory[pageIndex]
  131. # now, have page 'page' at index 'pageIndex' in memory
  132. whenReferenced = len(addrList)
  133. # whenReferenced tells us when, in the future, this was referenced
  134. for futureIdx in range(addrIndex+1,len(addrList)):
  135. futurePage = int(addrList[futureIdx])
  136. if page == futurePage:
  137. whenReferenced = futureIdx
  138. break
  139. # print 'OPT: page %d is referenced at %d' % (page, whenReferenced)
  140. if whenReferenced >= maxReplace:
  141. # print 'OPT: ??? updating maxReplace (%d %d %d)' % (replaceIdx, replacePage, maxReplace)
  142. replaceIdx = pageIndex
  143. replacePage = page
  144. maxReplace = whenReferenced
  145. # print 'OPT: --> updating maxReplace (%d %d %d)' % (replaceIdx, replacePage, maxReplace)
  146. victim = memory.pop(replaceIdx)
  147. # print 'OPT: replacing page %d (idx:%d) because I saw it in future at %d' % (victim, replaceIdx, whenReferenced)
  148. else:
  149. # miss, but no replacement needed (page frame not full)
  150. victim = -1
  151. count = count + 1
  152. # now add to memory
  153. memory.append(n)
  154. if cdebug:
  155. print 'LEN (a)', len(memory)
  156. if victim != -1:
  157. assert(victim not in memory)
  158. # after miss processing, update reference bit
  159. if n not in ref:
  160. ref[n] = 1
  161. else:
  162. ref[n] += 1
  163. if ref[n] > clockbits:
  164. ref[n] = clockbits
  165. if cdebug:
  166. print 'REF (a)', ref
  167. if notrace == False:
  168. print 'Access: %d %s %s -> %12s <- %s Replaced:%s [Hits:%d Misses:%d]' % (n, hfunc(idx), leftStr, memory, riteStr, vfunc(victim), hits, miss)
  169. addrIndex = addrIndex + 1
  170. print ''
  171. print 'FINALSTATS hits %d misses %d hitrate %.2f' % (hits, miss, (100.0*float(hits))/(float(hits)+float(miss)))
  172. print ''