Browse Source

add related_info on page-replacement-policy algorithms

main
yuchen 9 years ago
parent
commit
4502881f06
2 changed files with 254 additions and 0 deletions
  1. +46
    -0
      related_info/lab3/page-replacement-policy.md
  2. +208
    -0
      related_info/lab3/page-replacement-policy.py

+ 46
- 0
related_info/lab3/page-replacement-policy.md View File

@ -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
```

+ 208
- 0
related_info/lab3/page-replacement-policy.py View File

@ -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 ''

Loading…
Cancel
Save