From 4502881f06cd3a14678cb41cd04dc44240e1c1fc Mon Sep 17 00:00:00 2001 From: yuchen Date: Mon, 30 Mar 2015 12:26:26 +0800 Subject: [PATCH] add related_info on page-replacement-policy algorithms --- related_info/lab3/page-replacement-policy.md | 46 ++++ related_info/lab3/page-replacement-policy.py | 208 +++++++++++++++++++ 2 files changed, 254 insertions(+) create mode 100644 related_info/lab3/page-replacement-policy.md create mode 100755 related_info/lab3/page-replacement-policy.py diff --git a/related_info/lab3/page-replacement-policy.md b/related_info/lab3/page-replacement-policy.md new file mode 100644 index 0000000..421eb20 --- /dev/null +++ b/related_info/lab3/page-replacement-policy.md @@ -0,0 +1,46 @@ +# 理解页置换算法 +## 选择四种替换算法(0:LRU置换算法,1:改进的clock 页置换算法,2:工作集页置换算法,3:缺页率置换算法)中的一种来设计一个应用程序(可基于python, ruby, C, C++,LISP等)模拟实现,并给出测试。请参考page-replacement-policy.py 代码或独自实现。 + +###page-replacement-policy.py 代码 + +#### 对模拟环境的抽象 + +虚拟页访问序列:addresses=1,2,3,4,0,5.... 这里面的最大值代表最大页号 +页替换算法:policy=FIFO, LRU, OPT, CLOCK +CLOCK算法用的bit位数:clockbits=1 +物理页帧大小:cachesize +实际保持的也访问序列:addrList [1,2,3,4,0,5,...] +物理页帧内容:memory [] 初始为空 +当前占用的页帧数量:count 初始位0 + +#### 执行过程描述 + + +``` +for nStr in addrList: + # for clock need to track the ref by reference bits + + try: + idx = memory.index(n) + hits = hits + 1 + if policy == 'LRU' : + .... + except: + idx = -1 #missing + miss = miss + 1 + + if idx=-1 and ...: #missing and need replacement + #if phy page frames are full + # for FIFO , LRU + # replace victim item from memory by " victim = memory.pop(0)" + + # for CLOCK + # find one page for the beginning of scan + # check ref[page] and update ref[page] + # find a victim which ref[page]=0 by memory.remove(page) + else: + # miss, but no replacement needed (phy page frame not full) + # now add to memory + + #update ref for clock replacement +``` diff --git a/related_info/lab3/page-replacement-policy.py b/related_info/lab3/page-replacement-policy.py new file mode 100755 index 0000000..0ae4d25 --- /dev/null +++ b/related_info/lab3/page-replacement-policy.py @@ -0,0 +1,208 @@ +#! /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 '' + + + + + + + + + + +