add related_info on page-replacement-policy algorithms
This commit is contained in:
parent
1bcd4b231f
commit
4502881f06
46
related_info/lab3/page-replacement-policy.md
Normal file
46
related_info/lab3/page-replacement-policy.md
Normal 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
related_info/lab3/page-replacement-policy.py
Executable file
208
related_info/lab3/page-replacement-policy.py
Executable 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…
Reference in New Issue
Block a user