1. 实验目的
存储管理的主要功能之一是合理地分配空间。请求页式管理是一种常用的虚拟存储管理技术。
本实验的目的是通过请求页式管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。
2. 实验内容与要求
(1)通过计算不同算法的命中率比较算法的优劣。同时也考虑了用户内存容量对命中率的影响。
页面失效次数为每次访问相应指令时,该指令所对应的页不在内存中的次数。在本实验中,假定页面大小为1k,用户虚存容量为32k,用户内存容量为4页到32页。
(2)produce_addstream通过随机数产生一个指令序列,共320条指令。
A、指令的地址按下述原则生成:
1)50%的指令是顺序执行的
2)25%的指令是均匀分布在前地址部分
3)25%的指令是均匀分布在后地址部分
B、具体的实施方法是:
1)在[0,319]的指令地址之间随机选取一起点m;
2)顺序执行一条指令,即执行地址为m+1的指令;
3)在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m’;
4)顺序执行一条指令,地址为m’+1的指令
5)在后地址[m’+2,319]中随机选取一条指令并执行;
6)重复上述步骤1)~5),直到执行320次指令
C、将指令序列变换称为页地址流
在用户虚存中,按每k存放10条指令排列虚存地址,即320条指令在虚存中的存放方式为:
第0条~第9条指令为第0页(对应虚存地址为[0,9]);
第10条~第19条指令为第1页(对应虚存地址为[10,19]);
。。。。。。
第310条~第319条指令为第31页(对应虚存地址为[310,319]);
按以上方式,用户指令可组成32页。
(3)计算并输出下述算法在不同内存容量下的命中率。
1)最佳置换算法(OPT);
2)先进先出算法(FIFO);
3)最近最久未使用页面置换(LRU);
4)最少使用页面淘汰算法(LFU)
3. 流程图与模块调用
4. 实验分析
(1)创建指令集
def progress():
set = []
m = np.random.randint(0, 319) #生成320条指令
for i in range(80): #2 条是顺序执行,1 条是前地址部分,1 条是后地址部分
set.append(m+1)
n = np.random.randint(0, m+1)
set.append(n)
set.append(n+1)
m = np.random.randint(n+2, 319)
set.append(m)
return set
(2)FIFO
def FIFO(n, ins):
u_set = []
hit = 0
for i in ins:
if i // 10 in u_set:
hit += 1
else:
if len(u_set) == n: #使用 pop(0) 和 append 来实现移出内存和进入内存的操作
u_set.pop(0)
u_set.append(i // 10)
return hit / len(ins)
(3)OPT
def OPT(n, ins):
hit = 0
u_set = [] #使用字典来保存下一个指令的位置
dic = dict.fromkeys(range(32), [])
for (ind, i) in enumerate(ins):
dic[i // 10] = dic[i // 10] + [ind]
for (ind, i) in enumerate(ins):
dic[i // 10].pop(0)
if (i // 10) in u_set:
hit += 1
else:
if len(u_set) == n:
temp = [321] * n
for (index, page) in enumerate(u_set):
if len(dic[page]) > 0:
temp[index] = dic[page][0]
u_set.pop(np.argmax(temp))
u_set.append(i // 10)
return hit / len(ins)
(4)LRU
def LRU(n, ins):
u_set = []
hit = 0
for i in ins: #当访问内存中已经存在的页面时,将该页面放在最后面
if i // 10 in u_set:
hit += 1
temp = u_set.pop(u_set.index(i//10))
u_set.append(temp)
else:
if len(u_set) == n:
u_set.pop(0)
u_set.append(i//10)
return hit / len(ins)
(5)LFU
def LFU(n, ins):
u_set = []
hit = 0 #采用的是访问的早晚来判断一个页面再次被访问的可能
for (ind, i) in enumerate(ins):
if i // 10 in u_set:
hit += 1
else:
if len(u_set) == n:
temp = [0] * n
for item in ins[max(0, ind - 20):ind]:
for k in range(n):
if u_set[k] == item // 10:
temp[k] += 1
break
u_set.pop(np.argmin(temp))
u_set.append(i // 10)
return hit / len(ins)
5. 总代码
import numpy as np
import matplotlib.pyplot as plt
#coding:utf-8
def progress():
set = []
m = np.random.randint(0, 319)
for i in range(80):
set.append(m+1)
n = np.random.randint(0, m+1)
set.append(n)
set.append(n+1)
m = np.random.randint(n+2, 319)
set.append(m)
return set
def FIFO(n, ins):
u_set = []
hit = 0
for i in ins:
if i // 10 in u_set:
hit += 1
else:
if len(u_set) == n:
u_set.pop(0)
u_set.append(i // 10)
return hit / len(ins)
def OPT(n, ins):
hit = 0
u_set = []
dic = dict.fromkeys(range(32), [])
for (ind, i) in enumerate(ins):
dic[i // 10] = dic[i // 10] + [ind]
for (ind, i) in enumerate(ins):
dic[i // 10].pop(0)
if (i // 10) in u_set:
hit += 1
else:
if len(u_set) == n:
temp = [321] * n
for (index, page) in enumerate(u_set):
if len(dic[page]) > 0:
temp[index] = dic[page][0]
u_set.pop(np.argmax(temp))
u_set.append(i // 10)
return hit / len(ins)
def LRU(n, ins):
u_set = []
hit = 0
for i in ins:
if i // 10 in u_set:
hit += 1
temp = u_set.pop(u_set.index(i//10))
u_set.append(temp)
else:
if len(u_set) == n:
u_set.pop(0)
u_set.append(i//10)
return hit / len(ins)
def LFU(n, ins):
u_set = []
hit = 0
for (ind, i) in enumerate(ins):
if i // 10 in u_set:
hit += 1
else:
if len(u_set) == n:
temp = [0] * n
for item in ins[max(0, ind - 20):ind]:
for k in range(n):
if u_set[k] == item // 10:
temp[k] += 1
break
u_set.pop(np.argmin(temp))
u_set.append(i // 10)
return hit / len(ins)
def main():
print("Start memory management.")
print("Producing address flow, wait for while, please.")
ins = progress()
result = np.zeros([4, 29])
x = np.arange(4, 33)
for i in x:
result[0, i-4] = OPT(i, ins)
result[1, i-4] = FIFO(i, ins)
result[2, i-4] = LRU(i, ins)
result[3, i-4] = LFU(i, ins)
print("There are algorithms in the program")
print("\t1、Optimization algorithm")
print("\t2、First in first out algorithm")
print("\t3、Least recently used algorithm")
print("\t4、Least frequently used algorithm")
Select=True
plt.figure(figsize=(8, 4))
while(Select):
num=int(input("\tSelect an algorithm number, please\n\t<<<"))
if num==1:
plt.plot(x, result[0], label="OPT")
plt.legend()
plt.show()
elif num==2:
plt.plot(x, result[1], label="FIFO")
plt.legend()
plt.show()
elif num==3:
plt.plot(x, result[2], label="LRU")
plt.legend()
plt.show()
elif num==4:
plt.plot(x, result[3], label="LFU")
plt.legend()
plt.show()
else:
print("there is not the algorithm in the program.\n")
ch=input("do you try again with another algorithm(y/n)\n\t<<<")
if(ch=='y'):
Select=True
else:
Select==False
break
plt.figure(figsize=(8, 4))
plt.plot(x, result[0], label="OPT")
plt.plot(x, result[1], label="FIFO")
plt.plot(x, result[2], label="LRU")
plt.plot(x, result[3], label="LFU")
plt.legend()
plt.show()
return
if __name__ == '__main__':
main()
6. 运行情况
(1)操作终端
(2)OPT
(3)FIFO
(4)LRU
(5)LFU
(6)对比图