#include "cachelab.h" #include #include #include #include #include typedef struct { unsigned tag; unsigned usedtime; } block; block *cache; int getOpt(int argc,char **argv,int *s,int *E,int *b,int *verbose,char *tracefile); void printHelpMenu(); void cacheStateOut(char op,int type); void find(char op,unsigned addr,unsigned size,int time); int hit,miss,eviction; int verbose; int s,E,b; int main(int argc,char **argv) { FILE *fp; char tracefile[100]; char op[10]; unsigned addr,size; int t; getOpt(argc,argv,&s,&E,&b,&verbose,tracefile); // get option if(s<0||E<0||b<1){ printf("Invalid Cache parameter\n\n"); exit(1); } cache = (block *)malloc(sizeof(block)* E< 0){ if(verbose) printf("%s %x,%d ",op,addr,size); switch(op[0]){ case 'M': hit++; case 'L': case 'S': find(op[0],addr,size,++t); } } printSummary(hit, miss, eviction); free(cache); fclose(fp); return 0; } void find(char op, unsigned addr,unsigned size,int time){ int i; unsigned tag = addr >>b >>s ; unsigned set_index = addr >> b &((1<0 && cache_set[i].tag ==tag){ //hit cache_set[i].usedtime = time; hit++; if(verbose) cacheStateOut(op,0); return; } else if(!cache_set[i].usedtime){ // empty block miss++; cache_set[i].tag = tag; cache_set[i].usedtime = time; if(verbose) cacheStateOut(op,1); return; } else if(cache_set[i].usedtime < eviction_block->usedtime) // !=tag , current block is older eviction_block = cache_set+i; } miss ++; eviction ++; eviction_block->tag = tag; // replace sacrifice cacheline eviction_block->usedtime = time; if(verbose) cacheStateOut(op,2); return ; } int getOpt(int argc,char **argv,int *s,int *E,int *b,int *verbose,char *tracefile) { int oc; while((oc=getopt(argc,argv,"hvs:E:b:t:"))!=-1){ switch(oc){ case 'h': printHelpMenu();break; // print usage case 'v': *verbose=1;break; case 's': *s = atoi(optarg);break; case 'E': *E = atoi(optarg);break; case 'b': *b = atoi(optarg);break; case 't': strcpy(tracefile,optarg);break; default : printf("input error\n");break; } } return 0; } void cacheStateOut(char op,int type){ switch(type){ case 0: //hit switch(op){ case 'L': case 'S':printf("hit\n");break; case 'M':printf("hit hit\n");break; }break; case 1: //miss switch(op){ case 'L': case 'S':printf("miss\n");break; case 'M':printf("miss hit\n");break; } case 2: //eviction switch(op){ case 'L': case 'S':printf("miss eviction\n");break; case 'M':printf("miss eviction hit\n");break; }break; } } void printHelpMenu(){ printf("Usage: ./csim [-hv] -s -E -b -t \n"); printf("Options:\n"); printf("-h Print this help message.\n"); printf("-v Optional verbose flag.\n"); printf("-s Number of set index bits.\n"); printf("-E Number of lines per set.\n"); printf("-b Number of block offset bits.\n"); printf("-t Trace file.\n\n\n"); printf("Examples:\n"); printf("linux> ./csim -s 4 -E 1 -b 4 -t traces/yi.trace\n"); printf("linux> ./csim -v -s 8 -E 2 -b 4 -t traces/yi.trace\n"); } void checkOptarg(char *curOptarg){ if(curOptarg[0]=='-'){ printf("./csim :Missing required command line argument\n"); printHelpMenu(); exit(0); } }