|
|
- #! /usr/bin/env python
-
- import sys
- from optparse import OptionParser
- import random
- import math
-
- def hfunc(index):
- if index == -1:
- return 'MISS'
- else:
- return 'HIT '
-
- def vfunc(victim):
- if victim == -1:
- return '-'
- else:
- return str(victim)
-
- #
- # main program
- #
- parser = OptionParser()
- 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')
- parser.add_option('-p', '--policy', default='FIFO', help='replacement policy: FIFO, LRU, OPT, CLOCK', action='store', type='string', dest='policy')
- parser.add_option('-b', '--clockbits', default=1, help='for CLOCK policy, how many clock bits to use', action='store', type='int', dest='clockbits')
- parser.add_option('-f', '--pageframesize', default='3', help='size of the physical page frame, in pages', action='store', type='string', dest='pageframesize')
- parser.add_option('-s', '--seed', default='0', help='random number seed', action='store', type='string', dest='seed')
- parser.add_option('-N', '--notrace', default=False, help='do not print out a detailed trace', action='store_true', dest='notrace')
- parser.add_option('-c', '--compute', default=False, help='compute answers for me', action='store_true', dest='solve')
-
- (options, args) = parser.parse_args()
-
- print 'ARG addresses', options.addresses
- print 'ARG policy', options.policy
- print 'ARG clockbits', options.clockbits
- print 'ARG pageframesize', options.pageframesize
- print 'ARG seed', options.seed
- print 'ARG notrace', options.notrace
- print ''
-
- addresses = str(options.addresses)
- pageframesize = int(options.pageframesize)
- seed = int(options.seed)
- policy = str(options.policy)
- notrace = options.notrace
- clockbits = int(options.clockbits)
-
- random.seed(seed)
-
- addrList = []
- addrList = addresses.split(',')
-
- if options.solve == False:
- print 'Assuming a replacement policy of %s, and a physical page frame of size %d pages,' % (policy, pageframesize)
- print 'figure out whether each of the following page references hit or miss'
-
- for n in addrList:
- print 'Access: %d Hit/Miss? State of Memory?' % int(n)
- print ''
-
- else:
- if notrace == False:
- print 'Solving...\n'
-
- # init memory structure
- count = 0
- memory = []
- hits = 0
- miss = 0
-
- if policy == 'FIFO':
- leftStr = 'FirstIn'
- riteStr = 'Lastin '
- elif policy == 'LRU':
- leftStr = 'LRU'
- riteStr = 'MRU'
- elif policy == 'OPT' or policy == 'CLOCK':
- leftStr = 'Left '
- riteStr = 'Right'
- else:
- print 'Policy %s is not yet implemented' % policy
- exit(1)
-
- # track reference bits for clock
- ref = {}
-
- cdebug = False
-
- # need to generate addresses
- addrIndex = 0
- for nStr in addrList:
- # first, lookup
- n = int(nStr)
- try:
- idx = memory.index(n)
- hits = hits + 1
- if policy == 'LRU' :
- update = memory.remove(n)
- memory.append(n) # puts it on MRU side
- except:
- idx = -1
- miss = miss + 1
-
- victim = -1
- if idx == -1:
- # miss, replace?
- # print 'BUG count, pageframesize:', count, pageframesize
- if count == pageframesize:
- # must replace
- if policy == 'FIFO' or policy == 'LRU':
- victim = memory.pop(0)
- elif policy == 'CLOCK':
- if cdebug:
- print 'REFERENCE TO PAGE', n
- print 'MEMORY ', memory
- print 'REF (b)', ref
- # hack: for now, do random
- # victim = memory.pop(int(random.random() * count))
- victim = -1
- while victim == -1:
- page = memory[int(random.random() * count)]
- if cdebug:
- print ' scan page:', page, ref[page]
- if ref[page] >= 1:
- ref[page] -= 1
- else:
- # this is our victim
- victim = page
- memory.remove(page)
- break
-
- # remove old page's ref count
- if page in memory:
- assert('BROKEN')
- del ref[victim]
- if cdebug:
- print 'VICTIM', page
- print 'LEN', len(memory)
- print 'MEM', memory
- print 'REF (a)', ref
-
- elif policy == 'OPT':
- maxReplace = -1
- replaceIdx = -1
- replacePage = -1
- # print 'OPT: access %d, memory %s' % (n, memory)
- # print 'OPT: replace from FUTURE (%s)' % addrList[addrIndex+1:]
- for pageIndex in range(0,count):
- page = memory[pageIndex]
- # now, have page 'page' at index 'pageIndex' in memory
- whenReferenced = len(addrList)
- # whenReferenced tells us when, in the future, this was referenced
- for futureIdx in range(addrIndex+1,len(addrList)):
- futurePage = int(addrList[futureIdx])
- if page == futurePage:
- whenReferenced = futureIdx
- break
- # print 'OPT: page %d is referenced at %d' % (page, whenReferenced)
- if whenReferenced >= maxReplace:
- # print 'OPT: ??? updating maxReplace (%d %d %d)' % (replaceIdx, replacePage, maxReplace)
- replaceIdx = pageIndex
- replacePage = page
- maxReplace = whenReferenced
- # print 'OPT: --> updating maxReplace (%d %d %d)' % (replaceIdx, replacePage, maxReplace)
- victim = memory.pop(replaceIdx)
- # print 'OPT: replacing page %d (idx:%d) because I saw it in future at %d' % (victim, replaceIdx, whenReferenced)
- else:
- # miss, but no replacement needed (page frame not full)
- victim = -1
- count = count + 1
-
- # now add to memory
- memory.append(n)
- if cdebug:
- print 'LEN (a)', len(memory)
- if victim != -1:
- assert(victim not in memory)
-
- # after miss processing, update reference bit
- if n not in ref:
- ref[n] = 1
- else:
- ref[n] += 1
- if ref[n] > clockbits:
- ref[n] = clockbits
-
- if cdebug:
- print 'REF (a)', ref
-
- if notrace == False:
- print 'Access: %d %s %s -> %12s <- %s Replaced:%s [Hits:%d Misses:%d]' % (n, hfunc(idx), leftStr, memory, riteStr, vfunc(victim), hits, miss)
- addrIndex = addrIndex + 1
-
- print ''
- print 'FINALSTATS hits %d misses %d hitrate %.2f' % (hits, miss, (100.0*float(hits))/(float(hits)+float(miss)))
- print ''
-
-
-
-
-
-
-
-
-
-
-
|