【Python学习笔记】29:模拟OPT和LRU算法

LRU之前做过,OPT 最佳淘汰算法是一种理想状态的算法,是去寻找后面没有使用,或者最晚使用的那个cache中的页面淘汰掉。

急着回去睡觉,不废话了。

代码实现

#-*-coding:utf-8-*-
from numpy import *

#一行四个输出
def MyPrint(lst,strlst):
	i=0
	for j in range(len(lst)):
		print strlst,'[',j,']=',lst[j],
		i+=1
		if i%4==0:
			print

#生成并输出地址表
def VtrAds():
	a=[-1 for i in range(256)] #存虚拟地址的数组
	#放入顺序增长的地址,每次4个
	index=0
	for i in range(32):
		index+=random.randint(0,4) #随机地加一点
		RandAds=random.randint(12767,22767) #随机生成一个起始地址
		#写入连续地址
		a[index]=RandAds
		a[index+1]=RandAds+1
		a[index+2]=RandAds+2
		a[index+3]=RandAds+3
		index+=4 #跳跃到下一个位置
	#放入较小的地址
	index=0
	skip=False #决定要不要跳过(交叉放入)
	lftCount=0
	while(True):
		#如果放入的数目足够了就结束循环
		if lftCount>=64:
			break
		#如果能放并且不用跳过
		if a[index]<0 and skip==False:
			a[index]=random.randint(0,12766) #放入一个小地址
			lftCount+=1 #记录成功放入了一次
			skip=True #下次就需要跳过了
		#如果能放入但需要跳过
		elif a[index]<0 and skip==True:
			skip=False #下次就不用跳过了
		index+=1 #指向下一个需要选择的地址
	#放入较大的地址
	for index in range(256):
		#只要是空的
		if a[index]<0:
			a[index]=random.randint(22768,32767) #就直接放入
	a=array(a) #转换为numpy数组
	#a=reshape(a,(-1,4)) #每行4个
	#按行输出
	print 'THE VIRTUAL ADDRESS STREAM AS FOLLOWS:'
	MyPrint(a,'a')
	print '='*30
	return a

#OPT算法
def MyOpt(i,a):
	print '-'*30
	print 'PAGE NUMBER WITH SIZE %dk FOR EACH ADDRESS IS:'%i
	yita=i*1024 #表示页面大小
	pageno=[num/yita+1 for num in a]
	'''
	pageno=a/yita
	#变成int
	for j in range(len(pageno)):
		pageno[j]=int(pageno[j])
	'''
	MyPrint(pageno,'pageno')
	print 'page assigned',' '*20,'page_in/total reference'
	for lnth in range(4,34,2):
		ok=getInOpt(lnth,pageno)
		print lnth,' '*40,ok

'''
#判断元素是否在列表里
def isIn(a,lst):
	for b in lst:
		if a==b:
			return True
	return False
'''

#获取OPT命中率
def getInOpt(lnth,pageno):
	cache=[]
	innum=0
	#对于需要的每个页面
	for i in range(len(pageno)):
		'''
		if len(cache)==0: #小心越界,单独判断
			cache.append(pageno[i]) #把页面加入进来
			continue
		'''
		#如果已经在cache里面
		if pageno[i] in cache:
			innum+=1
			continue #直接使用就行了,进入下一次
		#如果不在,但cache未满
		elif len(cache)<lnth:
			cache.append(pageno[i]) #把页面加入进来
		else: #OPT的核心(如果cache满时缺页)
			cache=lossOpt(cache,pageno,i) #更新cache
	return float(innum)/len(pageno)

#用于在Opt算法下更新cache
def lossOpt(cache,pageno,i):
	#bye数组记录哪个页不要了
	bye=[False for j in range(len(cache))]
	num=0 #记录已经有几个要留下
	#循环去看后面的每个页pageno[j]
	for j in range(i+1,len(pageno)):
		if num==len(cache)-1: #如果已经找到这么多
			break
		#如果有新的缺页项
		if (pageno[j] in cache)\
				and (bye[cache.index(pageno[j])]==False):
					num+=1 #新的缺页项
					bye[cache.index(pageno[j])]=True
	#拿掉那个还是False的
	#即使后面的元素不够多,在循环体外拿掉也是正确的
	for k in range(len(bye)):
		if bye[k]==False:
			del cache[k]
			break #拿掉一个就退出!
	return cache #返回新的cache

#获取LRU命中率
def getInLru(lnth,pageno):
	cache=[]
	innum=0 #命中次数
	for i in range(len(pageno)): #每个页面号i 
    		if pageno[i] not in cache: #如果不在cache中,即缺页 
        		if len(cache)<lnth: #如果cache未满
				#就在其尾部添加这一页(新加的在后面)
            			cache.append(pageno[i])  
        		else: #如果cache满了
				#拿掉最不常用的(在最前)
				#即把后面的前移
            			cache[0:lnth-1:]=cache[1:lnth:]
            			cache[lnth-1::]=[pageno[i]] #将这页放在最后 
    		else: #如果在cache中,即命中,注意这时不能用lnth了
			innum+=1 #记录
			#这时候要把那个页放到最后面,不改变其它的相对顺序
			#将它之后的页都复制到从它向后的位置
			#并在最后留一个空位保证不改变cache长度
			#所以保守地显示指明len(cache)-1
			cache[cache.index(pageno[i]):len(cache)-1:]=\
					cache[cache.index(pageno[i])+1::]
			#把这一页放在最后(最新)
			cache[len(cache)-1::]=[pageno[i]]
	return float(innum)/len(pageno)

#LRU算法
def MyLru(i,a):
	print '-'*30
	print 'PAGE NUMBER WITH SIZE %dk FOR EACH ADDRESS IS:'%i
	yita=i*1024 #表示页面大小
	pageno=[num/yita+1 for num in a]
	MyPrint(pageno,'pageno')
	print 'page assigned',' '*20,'page_in/total reference'
	for lnth in range(4,34,2):
		ok=getInLru(lnth,pageno)
		print lnth,' '*40,ok
	

#便利函数作入口
def Go():
	a=VtrAds() #生成地址表a
	print '输入OPT/LRU选择算法:'
	name=raw_input() #输入算法名称
	if name!='OPT' and name!='LRU':
		print '错误的输入,再见!'
		return
	print 'The algorithm is:',name
	#执行算法
	if name=='OPT':
		for i in (1,2,4,8):
			MyOpt(i,a)
	elif name=='LRU':
		for i in (1,2,4,8):
			MyLru(i,a)

测试

随机地址表,按照要求一半是顺序执行,一半均匀散布在低地址,一半均匀散步在高地址。
这里写图片描述

这里写图片描述

页面大小取1k,2k,4k,8k,然后对每个页面大小,取cache能存的页数从4~32(步长2),测试一下快表命中率
这里写图片描述

cache能存的页面数一样时,页面越大,命中率越大,因为一个页面能包容的地址更多了。

页面大小一样时,cache能存的页面数越多,命中率越大,因为cache里存的页面多了,自然更容易命中了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值