赞
踩
设计和实现最佳置换算法、先进先出置换算法、最近最久未使用置换算法、页面缓冲置换算法;通过页面访问序列随机发生器实现对上述算法的测试及性能比较。
/*********生成页面访问序列********/ void generate() { srand ( (unsigned) time (NULL)); //用时间做种,每次产生随机数不一样 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; } } printf("生成的页面随机访问序列:\n"); for(int i=0;i<32;i++) { printf("%d ", access[i]); } printf("\n"); }
typedef struct LNode
{
int data;
int flag; //访问位
int modify; //修改位
struct LNode *next;
}LNode;
typedef struct Link
{
int num;//当前链表上的结点数
LNode *next;
}Link;
主要函数如下:
bool isInNodes(int n);//页面是否已经在链表中
void addToLink(int data, int type);/页面添加到已修改页面链表和空闲链表上
void emptyIdle();//将空闲链表上的所有页面送出内存
void emptyModi();//将已修改页面链表上所有的链表送出内存
void PBA(int n);//PBA算法实现函数
void PBA_ALL();//处理随机生成器生成的页面序列并计算缺页率
void PBA (int n) { if (isInNodes (n)) { printf ("已装入内存\n"); } else if (index == size) { struct 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++; } }
typedef struct node
{
int num;//页号
node* next;//下一个结点页面
} Node, *pNode;
typedef struct queue
{
int n;//总的结点数
pNode front;//队首指针
pNode rear; //队尾指针
} Queue, *pQueue;
主要函数如下:
void initQueue(pQueue q);//初始化队列
void push(pQueue q, int num);//队列中加入新的页面结点
void pop(pQueue q);//将页面移出内存
void destroy (pQueue q);//销毁队列
bool findInQueue (pQueue q, int num);//查找页面是否已经调入内存
void fifo(pQueue q, int num);//先进先出置换算法实现函数
void FIFO_ALL();//处理随机生成器生成的页面序列并计算缺页率
void fifo(pQueue q, int num) { if (findInQueue (q, num)) { printf ("已装入内存\n"); } else { if(q->n==size) { pop(q); push(q, num); lost++; } else { push(q, num); } } }
void LRU(int n) { int i, j; if (isInMemo(n)) { printf ("已经装入内存\n"); } else if (index == size) { int max = n, pos = -1, tag; for (i = 0; i < size; i++) { for (j = n - 1; j >= 0; j--) { if (access[j] == memo[i]) { tag = j; break; } } if (tag < max) { max = tag; pos = i; if (max == 0) { break; } } } memo[pos] = access[n]; lost++; } else { memo[index] = access[n]; index++; } }
void OPT(int n) { int i = 0, j = 0; if (isInMemo (n)) { printf ("页面已被调入\n"); } else if (index == size) { lost++; int max = 0, pos, tag; for (i = 0; i < size; i++) { tag = -1; for (j = n + 1; j < 32; j++) { if (access[j] == memo[i]) { tag = j; break; } } if (tag == -1) { max = 32; pos = i; break; } else { if (max < tag) { max = tag; pos = i; } } } memo[pos] = access[n]; } else { memo[index] = access[n]; index++; } }
生成随机序列access[32]={63, 58, 58, 60, 60, 63, 58, 63, 26, 28, 29, 31, 31, 27, 30, 28, 27, 31, 31, 31, 27, 34, 32, 33, 28, 31, 30, 30, 33, 28, 34, 34}
PBA算法处理结果及缺页率:
可以看到,32个页面,有13个页面发生了缺页,缺页率为0.406
FIFO算法处理结果及缺页率:
可以看到,32个页面,有18个页面发生了缺页,缺页率为0.563
LRU算法处理结果及缺页率:
可以看到,32个页面,有17个页面发生了缺页,缺页率为0.531
OPT算法处理结果及缺页率:
可以看到,32个页面,有12个页面发生了缺页,缺页率为0.375
利用genenrate()函数再生成几个访问序列,记录得到如下表格的形式表示:
访问序列的长度始终为32,默认初始分配给每种算法的内存空间块数为3
置换算法 | PBA | FIFO | LRU | OPT | |
---|---|---|---|---|---|
测试序列1 | 缺页数 | 13 | 18 | 17 | 12 |
缺页率 | 0.41 | 0.56 | 0.53 | 0.38 | |
测试序列2 | 缺页数 | 18 | 20 | 21 | 17 |
缺页率 | 0.56 | 0.63 | 0.66 | 0.53 | |
测试序列3 | 缺页数 | 11 | 11 | 12 | 9 |
缺页率 | 0.34 | 0.34 | 0.38 | 0.28 |
从上图以及表格可以分析出:
(1) 同一种算法,对于不同的访问序列,其缺页率是不同,会有所变化。
(2) 总的来看,最佳置换算法的缺页率是最低的。剩下的集中算法中,页面缓冲算法的缺页率要低于其他置换算法。先进先出算法和最近最久未使用算法性能相近。
实验完整源码请点击(Github)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。