#include #include //structs for my cache, lines, sets, and a cache struct line_t{ int tag; int timestamp; int valid; }; typedef struct line_t line; struct set_t{ line * lines; }; typedef struct set_t set; struct cache_t{ int num_sets; int associativity; int block_size; set * sets; }; typedef struct cache_t cache; cache * makeCache(int lines, int lps, int blocksize); int cache_lookup(long address, cache *cache); int main (int argc, char *argv[]) { int total =0; int hits = 0; int num_lines = atoi(argv[1]), lines_per_set = atoi(argv[2]), bytes_per_block = atoi(argv[3]); cache * cache = makeCache(num_lines,lines_per_set,bytes_per_block); char line[80]; // printf("Simulating cache with:\n"); // printf(" - Total lines = %d\n", num_lines); // printf(" - Lines per set = %d\n", lines_per_set); // printf(" - Block size = %d bytes\n", bytes_per_block); while (fgets(line, 80, stdin)) { long addr_req = strtol(line, NULL, 0); /* simulate cache fetch with address `addr_req` */ // printf("Processing request: 0x%lX\n", addr_req); int hit = cache_lookup(addr_req, cache); if(hit) ++hits; ++total; } printf("Hit rate: %f | Miss rate: %f\n",(double)hits/total,(total-(double)hits)/total);//left as numbers 0-1 beacuse that is how we do it in math 474. Also, truncating seems useless. return 0; //I'm letting the OS garbage collect for me, I could easily do this (note the time of the last commit vs. midnight), but it seems like CS116 level busy work. } cache * makeCache(int lines, int lps, int blocksize){ cache * this =malloc(sizeof(cache));//initialize all the stuff this->num_sets = lines/lps; this->associativity=lps; this->block_size=blocksize; this->sets=malloc(sizeof(set)*lines); int i; for(i = 0; i<(this->num_sets);++i){ //not sure if this is the best way to do this. Seems wrong. (this->sets+i)->lines = malloc(sizeof(line)*lps); int j; for(j=0;jsets+i)->lines[j]).valid=0; } } return this; } int cache_lookup(long address, cache *cache) { static unsigned int timestamp = 0;//code taken from piazza. aparrently it was given to us. this is kinda the whole lab... idk why it was given to us. int set_idx = (address / cache->block_size) % cache->num_sets; // remove the bits required for block offset, then modulo to get the correct set num. int tag = (address / cache->block_size) / cache->num_sets; //tag is what's left over. // printf("set_idx %d, tag %d\n", set_idx, tag); int i,hit=0;//sample code had a j, which was never used. I took it out when I saw a compiler warning about it. set *set = cache->sets + set_idx;//get the set for (i=0; iassociativity;i++) {//search the set if (set->lines[i].valid && set->lines[i].tag == tag) { hit =1; break; } } if (hit) {//whoo! you found it, just poke the timestamp and you're done. set->lines[i].timestamp = ++timestamp; return 1; } else { //make a new spot for it, evicting the LRU item. int spot = 0; int minstamp = set->lines[0].timestamp; for (i=0; iassociativity;i++) { if(set->lines[i].timestamplines[i].timestamp; spot = i; } if (!(set->lines[i].valid)) {//if one of them isnt valid, you can just fill the spot rather than evict. set->lines[i].valid=1; set->lines[i].timestamp = ++timestamp; set->lines[i].tag = tag; return 0; } } set->lines[spot].valid=1;//pack your boxes, the sherrif is here to evict you. set->lines[spot].timestamp = ++timestamp; set->lines[spot].tag = tag; return 0; } }