CSAPP cache-lab

第一个用C写一个cache,我的代码:

#include
#include
#include
#include
#include
#define MAX 100


int s = 2, E = 1, b = 3;

struct cache_line{
    int valid;
    unsigned long tag;
    int time;

};

struct ins{
    unsigned long tag;
    int set;
    int type;    //  0 是L,1是store 2 是modify
};

struct cache_line **initCache(int s, int e){
    int S = 1<struct cache_line **cache;
    cache = (struct cache_line**)malloc(S*sizeof(struct cache_line*));
    for (int i = 0; i < S; i++){
        cache[i] = (struct cache_line*)malloc(e*sizeof(struct cache_line));
        for (int j = 0; j < e; j++){
            cache[i][j].valid = 0;
            cache[i][j].tag = 0;
            cache[i][j].time = 0;
        }
    }
    return cache;
}

void self_incre(struct cache_line **cache,int S,int E,int t)
{
    for(int i = 0;ifor(int j = 0;jint evict(struct cache_line** cache, int E, int set, unsigned long tag){
    int out = 0;
    for (int i = 0; iif (cache[set][i].time>cache[set][out].time){
            out = i;
        }
    }
    cache[set][out].valid = 1;
    cache[set][out].tag = tag;
    cache[set][out].time = 0;
    return out;
}


//cache[S][E]
int solve(struct cache_line **cache, int E, struct ins *ins1){
    int set = ins1->set;
    unsigned long tag = ins1->tag;
    int spare = -1;
    for (int i = 0; iif (cache[set][i].valid == 1 && cache[set][i].tag == tag){
            if (ins1->type == 2){
                self_incre(cache,(1<2);
                cache[set][i].time = 0;
                return 3;   //hit 0  hit hit 3
            }
            else{
                self_incre(cache,(1<1);
                cache[set][i].time = 0;
                return 0;
            }
        }
        else if (cache[set][i].valid == 0){
            spare = i;
        }
    }
    if (spare == -1){
        int out = evict(cache, E, set, tag);
        if (ins1->type == 2){
            self_incre(cache,(1<2);
            cache[set][out].time = 0;
            return 4;   //miss evict 1 miss evict hit  4
        }
        else{
            self_incre(cache,(1<1);
            cache[set][out].time = 0;
            return 1;
        }
    }
    else{
        cache[set][spare].valid = 1;
        cache[set][spare].tag = tag;
        if (ins1->type == 2){
            self_incre(cache,(1<2);
            cache[set][spare].time = 0;
            return 5;  //miss 2 miss hit 5
        }
        else{
            self_incre(cache,(1<1);
            cache[set][spare].time = 0;
            return 2;
        }
    }
    free(ins1);
}


//解析操作
struct ins* analysis_operation(char *address, int len, int s, int b){

    if (len<1)
        return NULL;
    int i = 1;
    unsigned long  add_decimal = 0;
    struct ins *ins1 = (struct ins*)malloc(sizeof(struct ins*));
    if (address[i] == 'L')
        ins1->type = 0;
    else if (address[i] == 'S')
        ins1->type = 1;
    else if (address[i] == 'M')
        ins1->type = 2;
    else
        return NULL;

    i = len - 1;
    while (i >= 1 && address[i] != ',')
        i--;
    i--;       //地址最低位
    int p = 0; //幂
    while (address[i] != ' '){
        int c = address[i];
        if (c >= 48 && c <= 57)
            add_decimal += (unsigned long)((c - 48)*((unsigned long)(1)<<(4*p)));
        else if (c >= 97 && c <= 102)
            add_decimal += (unsigned long)((c - 87)*((unsigned long)1<<(4*p)));
        p++;
        i--;
    }
    ins1->set = (add_decimal << (64 - s - b)) >> (64 - s);
    ins1->tag = add_decimal >> (s + b);
    return ins1;
}

int main(int argc, char *argv[]) {
    int hit=0, miss=0, eviction=0;

    FILE *f;
    char instr[MAX], trace[MAX];
    int opt=0;
    int vervose = 0;
    opterr = 0;
    while ((opt = getopt(argc, argv, "vs:E:b:t:")) != -1) //get basic infomation 
    {
        switch (opt) {
        case 'v':
            vervose = 1;    //help to debug
            break;
        case 's':
            s = atoi(optarg);
            break;
        case 'E':
            E = atoi(optarg);
            break;
        case 'b':
            b = atoi(optarg);
            break;
        case 't':
            strcpy(trace, optarg);
            break;
        }
    }

    struct cache_line **cache = initCache(s, E);
    f = fopen(trace, "r");
    while (fgets(instr, MAX, f) != NULL) {

        struct ins *ins1 = (struct ins*) analysis_operation(instr,
                strlen(instr) - 1, s, b);
        if (ins1 == NULL)
            continue;
        int k = solve(cache, E, ins1);
        switch (k) {
        case 0:
            hit++;
            break;
        case 1:
            miss++;
            eviction++;
            break;
        case 2:
            miss++;
            break;
        case 3:
            hit += 2;
            break;
        case 4:
            miss++;
            eviction++;
            hit++;
            break;
        case 5:
            miss++;
            hit++;
            break;
        default:
            break;
        }
        if (vervose) {
            switch (k) {
            case 0:
                printf("%s hit\n", instr + 1);
                break;
            case 2:
                printf("%s miss\n", instr + 1);
                break;
            case 5:
                printf("%s miss hit\n", instr + 1);
                break;
            case 1:
                printf("%s miss eviction\n", instr + 1);
                break;
            case 4:
                printf("%s miss eviction hit\n", instr + 1);
                break;

            }

        }

    }
        fclose(f);
        int S = 1 << s;
        for (int i = 0; i < S; i++)
            free(cache[i]);
        free(cache);
        printSummary(hit, miss, eviction);  //print results
        return 0;
}




你可能感兴趣的:(CS-grow之路)