第一个用C写一个cache,我的代码:
#include<stdlib.h>
#include<getopt.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#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<<s;
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;i<S;i++){
for(int j = 0;j<E;j++)
cache[i][j].time+=t;
}
}
int evict(struct cache_line** cache, int E, int set, unsigned long tag){
int out = 0;
for (int i = 0; i<E; i++){
if (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; i<E; i++){
if (cache[set][i].valid == 1 && cache[set][i].tag == tag){
if (ins1->type == 2){
self_incre(cache,(1<<s),E,2);
cache[set][i].time = 0;
return 3; //hit 0 hit hit 3
}
else{
self_incre(cache,(1<<s),E,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<<s),E,2);
cache[set][out].time = 0;
return 4; //miss evict 1 miss evict hit 4
}
else{
self_incre(cache,(1<<s),E,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<<s),E,2);
cache[set][spare].time = 0;
return 5; //miss 2 miss hit 5
}
else{
self_incre(cache,(1<<s),E,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;
}