|
|
- #include "cachelab.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <getopt.h>
-
- 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<<s);
- memset(cache,0,sizeof(block)* E<<s);
-
- fp = fopen (tracefile,"r");
- while(fscanf(fp,"%s%x,%d\n",op,&addr,&size) > 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<<s) -1);
- block *cache_set = cache + E * set_index ; // set address
- block *eviction_block = cache_set; // LRU cacheline
- for(i = 0;i<E;i++){
- if(cache_set[i].usedtime>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 <num> -E <num> -b <num> -t <file>\n");
- printf("Options:\n");
- printf("-h Print this help message.\n");
- printf("-v Optional verbose flag.\n");
- printf("-s <num> Number of set index bits.\n");
- printf("-E <num> Number of lines per set.\n");
- printf("-b <num> Number of block offset bits.\n");
- printf("-t <file> 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);
- }
- }
|