#include "cachelab.h"
#include <stdio.h>
#include <stdlib.h>
typedef long long ll;
/*以下为要用到的变量*/
typedef struct {
int val; //有效位
int lastVisit; //这一行上一次被使用的时间
ll tag; //这一行的tag
}line_type;
typedef struct {
line_type* line; //set里的行
int used; //已经被占用的行,used=E则这个set满了
}set_type;
typedef struct {
set_type* set;
int s, E, b;
}cache_type;
cache_type C;
int display = 0;
int hit_count = 0, miss_count = 0, eviction_count = 0;
int time = 0;
/*函数*/
char* readCMD(int argc, char** argv);
void readLINE(char opt, ll addr, int size);
void readFILE(char* name);
void Malloc();
void Free();
void Store(ll addr, int size);
void Load(ll addr, int size);
void Modify(ll addr, int size);
void error(int k);
ll getSet(ll addr, int s, int b);
ll getTag(ll addr, int t);
int main(int argc, char** argv) {
char* file = readCMD(argc, argv);
Malloc();
readFILE(file);
printSummary(hit_count, miss_count, eviction_count);
Free();
return 0;
}
ll getSet(ll addr, int s, int b) {
int mask = 0x7fffffff;
ll set;
mask >>= (31 - s);
addr >>= b;
set = mask & addr;
return set;
}
ll getTag(ll addr, int t) {
int mask = 0x7fffffff;
ll tag;
mask >>= (31 - t);
addr >>= (32 - t);
tag = mask & addr;
return tag;
}
char* readCMD(int argc, char** argv) {
int k = 1;
char *file;
while(k < argc) {
switch(argv[k][1]) {
case 'v':
display = 1;
k++;
case 's':
C.s = atoi(argv[k+1]);
k+=2;
case 'E':
C.E = atoi(argv[k+1]);
k+=2;
case 'b':
C.b = atoi(argv[k+1]);
k+=2;
case 't':
file = argv[k+1];
k+=2;
}
}
return file;
}
void readLINE(char opt, ll addr, int size) {
if(opt == 'S')
Store(addr, size);
else if(opt == 'L')
Load(addr, size);
else if(opt == 'M')
Modify(addr, size);
return;
}
void readFILE(char* name) {
ll addr;
int size;
char opt;
FILE *f = fopen(name, "r");
while(fscanf(f, "%c", &opt)==1) {
if(opt == ' ')
fscanf(f, "%c %llx,%d\n", &opt, &addr, &size);
else
fscanf(f, "%llx,%d\n", &addr, &size);
if(opt == 'I')
continue;
readLINE(opt, addr, size);
time++;
}
return;
}
void Load(ll addr, int size) {
ll set = getSet(addr, C.s, C.b);
set_type cSet = C.set[set];
int t = 32 - C.s - C.b;
ll tag = getTag(addr, t);
for(int i=0; i<C.E; i++) {
if(cSet.line[i].val == 1 && cSet.line[i].tag == tag) {
hit_count++;
C.set[set].line[i].lastVisit = time;
if(display)
printf("L %llx,%d hit\n", addr, size);
return;
}
}
miss_count++;
if(cSet.used == C.E) {
eviction_count++;
int Min = cSet.line[0].lastVisit;
int cnt = 0;
for(int i=1; i<C.E; i++) {
if(cSet.line[i].lastVisit < Min) {
Min = cSet.line[i].lastVisit;
cnt = i;
}
}
C.set[set].line[cnt].tag = tag;
C.set[set].line[cnt].lastVisit = time;
if(display)
printf("L %llx,%d miss eviction\n", addr, size);
return;
}
else {
int k = cSet.used;
C.set[set].line[k].val = 1;
C.set[set].line[k].tag = tag;
C.set[set].line[k].lastVisit = time;
C.set[set].used++;
if(display)
printf("L %llx,%d miss\n", addr, size);
return;
}
}
void Store(ll addr, int size) {
ll set = getSet(addr, C.s, C.b);
set_type cSet = C.set[set];
int t = 32 - C.s - C.b;
int S = 1 << C.s;
if(set >= S)
error(2);
ll tag = getTag(addr, t);
for(int i=0; i<C.E; i++) {
if(cSet.line[i].val == 1 && cSet.line[i].tag == tag) {
hit_count++;
C.set[set].line[i].lastVisit = time;
if(display)
printf("S %llx,%d hit\n", addr, size);
return;
}
}
miss_count++;
if(cSet.used == C.E) {
eviction_count++;
int Min = cSet.line[0].lastVisit;
int cnt = 0;
for(int i=1; i<C.E; i++) {
if(cSet.line[i].lastVisit < Min) {
Min = cSet.line[i].lastVisit;
cnt = i;
}
}
C.set[set].line[cnt].tag = tag;
C.set[set].line[cnt].lastVisit = time;
if(display)
printf("S %llx,%d miss eviction\n", addr, size);
return;
}
else {
int k = cSet.used;
C.set[set].line[k].val = 1;
C.set[set].line[k].tag = tag;
C.set[set].line[k].lastVisit = time;
C.set[set].used++;
if(display)
printf("S %llx,%d miss\n", addr, size);
return;
}
}
void Modify(ll addr, int size) {
int flag = 0;
printf("M %llx,%d", addr, size);
ll set = getSet(addr, C.s, C.b);
set_type cSet = C.set[set];
int S = 1 << C.s;
if(set >= S)
error(2);
int t = 32 - C.s - C.b;
ll tag = getTag(addr, t);
for(int i=0; i<C.E; i++) {
if(cSet.line[i].val == 1 && cSet.line[i].tag == tag) {
hit_count++;
flag = 1;
C.set[set].line[i].lastVisit = time;
if(display)
printf(" hit");
break;
}
}
if(!flag) {
miss_count++;
if(cSet.used == C.E) {
eviction_count++;
int Min = cSet.line[0].lastVisit;
int cnt = 0;
for(int i=1; i<C.E; i++) {
if(cSet.line[i].lastVisit < Min) {
Min = cSet.line[i].lastVisit;
cnt = i;
}
}
C.set[set].line[cnt].tag = tag;
C.set[set].line[cnt].lastVisit = time;
if(display)
printf(" miss eviction");
}
else {
int k = cSet.used;
C.set[set].line[k].val = 1;
C.set[set].line[k].tag = tag;
C.set[set].line[k].lastVisit = time;
C.set[set].used++;
if(display)
printf(" miss");
}
}
hit_count++;
printf(" hit\n");
}
void Malloc() {
int S = 1 << C.s;
C.set = malloc(sizeof(set_type) * S + 1);
for(int i=0; i<S; i++) {
C.set[i].line = malloc(sizeof(line_type) * C.E + 1);
C.set[i].used = 0;
for(int j=0; j<C.E; j++)
C.set[i].line[j].val = 0;
}
return;
}
void Free() {
int S = 1 << C.s;
for(int i=0; i<S; i++)
free(C.set[i].line);
free(C.set);
return;
}
void error(int k) {
switch(k) {
case 1:
printf("Malloc Error");
return;
case 2:
printf("OPT Error");
return;
}
}
CSAPP:cache lab
猜你喜欢
转载自blog.csdn.net/pkuout/article/details/76096042
今日推荐
周排行