设计和实现最佳置换算法、先进先出置换算法、最近最久未使用置换算法、页面缓冲置换算法;通过页面访问序列随机发生器实现对上述算法的测试及性能比较。
页表用整数数组或结构数组来表示
页面访问序列串是一个整数序列,整数的取值范围为0到N - 1。页面访问序列串中的每个元素p表示对页面p的一次访问
符合局部访问特性的随机生成算法
确定虚拟内存的尺寸N,工作集的起始位置p,工作集中包含的页数e,工作集移动率m(每处理m个页面访问则将起始位置p +1),以及一个范围在0和1之间的值t;生成m个取值范围在p和p + e间的随机数,并记录到页面访问序列串中;生成一个随机数r,0 ≤ r ≤ 1;如果r < t,则为p生成一个新值,否则p = (p + 1) mod N;如果想继续加大页面访问序列串的长度,请返回第2步,否则结束(1)最佳置换算法 最佳置换算法的主要思想是,在发生页面替换时,被替换的对象应该满足,在以后的页面访问中,该对象不会再次被访问或者较晚被访问。是一种理想化算法,具有最好性能(对于固定分配页面方式,本法可保证获得最低的缺页率),但实际上却难于实现,故主要用于算法评价参照 (2)先进先出置换算法 总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。实现方法为:把一个进程已调入内存的页面按先后次序链接成一个队列,并设置一个指针(称为替换指针),始终指向最老的页面。 (3)最近最久未使用置换算法 最近最久未使用置换算法的主要思想是,在发生页面替换时,被替换的页面应该满足,在之前的访问队列中,该对象截止目前未被访问的时间最长 (4)改进型Clock置换算法 改进型Clock置换算法的主要思想是,在每次页面替换时,总是尽可能地先替换掉既未被访问又未被修改的页面。 (5)页面缓冲算法 设立空闲页面链表和已修改页面链表采用可变分配和基于先进先出的局部置换策略,并规定被淘汰页先不做物理移动,而是依据是否修改分别挂到空闲页面链表或已修改页面链表的末尾,空闲页面链表同时用于物理块分配,当已修改页面链表达到一定长度如Z个页面时,一起将所有已修改页面写回磁盘,故可显著减少磁盘I/O操作次数
generate函数生成随机访问序列
void generate() { srand((unsigned)time(NULL)); //用时间做种,每次产生随机数不一样 int p = rand() % 64; int m = 8, e = 8; int i, j; double t; t = rand() % 10 / 10.0; for (i = 0; i < 4; i++) { for (j = i * m; j < (i + 1) *m; j++) { access[j] = (p + rand() % e) % 64; } double r = (rand() % 10) / 10.0; if (r < t) { p = rand() % 64; } else { p = (p + 1) % 64; } } }最佳置换算法
void testOptimal() { initMemo(); int i = 0; printf("最佳置换算法:\n"); for (; i < 32; i++) { optimal(i); printf("%d %d %d\n", memo[0], memo[1], memo[2]); } printf("最佳置换算法缺页率: / %d\n", lost / 32.0, lost); lost = 0; free(memo); index = 0; }先进先出算法
void fifoTest() { Queue q; pNode p; initQueue(&q); int i = 0; printf("先进先出置换算法\n"); for (; i < 32; i++) { fifo(&q, access[i]); p = q.front->next; while (p) { printf("%d ", p->num); p = p->next; } printf("\n"); } printf("先进先出算法缺页率:%f %d\n", lost / 32.0, lost); destroy(&q); }最近最久未使用算法
void testLRU() { int i; initMemo(); printf("最近最久未使用算法\n"); for (i = 0; i < 32; i++) { LRU(i); printf("%d %d %d\n", memo[0], memo[1], memo[2]); } printf("最近最久未使用缺页率: / %d \n", lost / 32.0, lost); lost = 0; index = 0; free(memo); }改进型clock置换算法
void test_Clock() { int i = 0, j = 0; printf("改进型Clock置换算法\n"); nodes = (LNode*)malloc(block * sizeof(LNode)); for (i = 0; i < block; i++) { nodes[i].data = -1; nodes[i].flag = -1; nodes[i].modify = -1; } for (i = 0; i < 32; i++) { updated_Clock(i); for (j = 0; j < block; j++) { printf("%d ", nodes[j].data); } printf("\n"); } printf("改进型Clock置换算法缺页率: / %d \n", lost / 32.0, lost); lost = 0; index = 0; }页面置换算法(PBA)
void PBA(int n) { if (isInNodes(n)) { printf("已装入内存\n"); } else if (index == size) { LNode *p; if ((p = isinLinks(n)) != NULL) { nodes = (LNode*)realloc(nodes, (size + 1) * sizeof(LNode)); nodes[size].data = p->data; nodes[size].flag = p->flag; nodes[size].modify = p->modify; nodes[size].next = p->next; free(p); size++; index++; } else { lost++;//缺页 if (nodes[n % 3].modify == 1) { addToLink(nodes[n % 3].data, 1); } else { addToLink(nodes[n % 3].data, 0); } nodes[n % 3].data = access[n]; nodes[n % 3].flag = 1; nodes[n % 3].next = NULL; if (rand() % 10 < 4) { nodes[n % 3].modify = 0; } else { nodes[n % 3].modify = 1; } } } else { nodes[index].data = access[n]; nodes[index].flag = 1; nodes[index].next = NULL; if (rand() % 10 < 4) { nodes[index].modify = 1; } else { nodes[index].modify = 0; } index++; } }generate函数产生的访问序列如下 最佳置换算法 12个页面发生了缺页,缺页率为0.375
先进先出算法 16个页面发生缺页,缺页率为0.5000
最近最久未使用算法 33个页面发生缺页,缺页率为1.031250
改进型Clock置换算法 18个页面发生缺页,缺页率为0.562500
页面缓冲置换算法 12个页面发生缺页,缺页率为0.375000
上述测试 分配给每种算法内存空间块数为3,改变分配空间块数为5
https://github.com/notdz56/16281023-/tree/master/操作系统第四次实验代码