时钟算法

时钟算法

计算机内存中,缓存是一种稀缺资源,虽然运行速度非常快,但是一个合理的算法能更好的提升性能.例如一个循环,在csapp一书中提到,是否合理的使用缓存的区域性.能影响两倍的性能.今天重点在页面置换的时钟算法不在这里过多描述.有兴趣的可以自行阅读,这个缓存区域性问题,在csapp中是很重视的.

算法数据结构描述

它就像一个时钟(顾名思义),但是却是一个只有时指针的时钟.刻度也是,没有分秒.但是这个时钟的移动却是为了寻找需要被替换的页面.
时钟算法
这里还有一个r 和w分别指,读写这个页面,它的写入我是没有做的,因为毕竟是描述这个算法.

工作方式

使用链表或者数组,但是我这里使用了链表.双向的.组成一个循环链表.每次寻找满足条件,r为为零就代表没有读过,也就是未使用,抛弃这个页面.如果为1就将这个页面置0,并指针向下移动.重复上述操作.直到找到满足条件.

结构体

typedef struct NODE {  //页面
    char read;
    char write;
    struct NODE *left;
    struct NODE *right;
    int date;
}node;
typedef struct CLOCK {     //时钟结构体sd
    int count; //时钟大小
    node * ptr;  //指针
    node *root;
}clock;

全部实现

#include<stdio.h>
#include<stdlib.h>
#include<String.h>
typedef struct NODE {  //页面
    char read;
    char write;
    struct NODE *left;
    struct NODE *right;
    int date;
}node;
typedef struct CLOCK {     //时钟结构体sd
    int count; //时钟大小
    node * ptr;  //指针
    node *root;
}clock;

void * Calloc(unsigned count , unsigned size);
node * readNode(node * n);
node *createnode(int size);
clock * init(int size);
node * position(node *root);
void moveNode(node * newNode, clock * cl);
void print(clock  *cl);
node * newNode(int date);

//包装器
void *Calloc(unsigned count, unsigned size) 
{
    void *ptr = NULL;
    if ((ptr = calloc(count, size)) == NULL) {
        fprintf(stderr, "Calloc error!\n");
        exit(-1);
    }
    else {
        return ptr;
    }
}
//通過驗證
node *createnode(int size)
{
    node *root = NULL;
    node *ptr = NULL;
    int  i = 0;
    root = (node*)Calloc(1, sizeof(node));
    root->date = 0;
    ptr = root;
    for (i = 1; i < size; i++) {
        ptr->right = (node*)Calloc(1, sizeof(node));
        ptr->right->left = ptr;
        ptr->date = i;
        ptr = ptr->right;
    }
    ptr->right = root;
    root->left = ptr;
    return root->left;
}

//初始化时钟
clock * init(int size)   //通過
{
    clock * root = (clock*)Calloc(1, sizeof(clock));
    root->count = size;
    root->root = createnode(size);
    root->ptr = root->root;
    return root;
}
//定位到符合条件的地方
node * position(node *root)
{
    node *tmp = root;
    while (1) {
        if (tmp->read == 0) {
            return tmp;
        }
        else {
            tmp->read = 0;
        }
        tmp = tmp->right;
    }

}

//页面置换 
void moveNode(node * new_node, clock * cl)
{
    node *ptr = position(cl->ptr);
    new_node->left = ptr->left;
    new_node->right = ptr->right;
    ptr->right->left = new_node;
    ptr->left->right = new_node;
    cl->ptr = new_node->right;
    if (ptr == cl->root) {
        cl->root = new_node;
    }
    free(ptr);
}
//遍历时钟
void print(clock  *cl) 
{   
    node *ptr = cl->root;
    node *ptrEnd = cl->root;
    printf("%d \n", ptr->date);
    ptr = ptr->right;
    while (ptr != ptrEnd) {
        printf("%d \n", ptr->date);
        ptr = ptr->right;
    }
}
//读数据
node * readNode(node * n)
{
    n->read = 1;
    return n;
}
//创建一个时钟节点
node * newNode(int date) 
{
    node * tmp = (node*)Calloc(1, sizeof(node));
    tmp->date = date;
    return tmp;
}
int main(void)
{
    clock * cl = init(10);
    node * tmp1 = newNode(20);
    node * tmp2 = newNode(21);
    node * tmp3 = newNode(22);
    node * tmp4 = newNode(23);
    node * tmp5 = newNode(24);
    node * tmp6 = newNode(25);
    node * tmp7 = newNode(26);
    node * tmp8 = newNode(27);
    print(cl);
    moveNode(tmp1,cl);
    printf("------------------------\n");
    print(cl);
    moveNode(tmp2, cl);
    printf("------------------------\n");
    print(cl);
    moveNode(tmp3, cl);
    printf("------------------------\n");
    print(cl);
    moveNode(tmp4, cl);
    printf("------------------------\n");
    print(cl);
    moveNode(tmp5, cl);
    printf("------------------------\n");
    print(cl);
    moveNode(tmp6, cl);
    printf("------------------------\n");
    print(cl);
    moveNode(tmp7, cl);
    moveNode(tmp8, cl);
    printf("------------------------\n");
    print(cl);
    system("pause");
    return 0;
}

这里因为篇幅已经很长了就不上运行结果.如果发现问题请帮忙指出.编写环境windows10 vs2017 如果是linux环境需要替换头文件,可以man查看.

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值