├── README ├── cache.c ├── cachesim └── traces ├── art.trace.gz ├── crafty_mem.trace.gz ├── mcf.trace.gz └── swim.trace.gz /README: -------------------------------------------------------------------------------- 1 | 1. Build the cache simulator. 2 | % cc -o cachesim cache.c -lm 3 | 4 | 2. Test the cache simulator. 5 | % gunzip -c traces/art.trace.gz | ./cachesim 6 | % gunzip -c traces/[name of trace] | ./cachesim [cachesim args] 7 | 8 | Example 1 9 | 10 | > gunzip -c traces/art.trace.gz | ./cachesim -a 1 -s 16 -l 16 -mp 30 11 | Cache parameters: 12 | Cache Size (KB) 16 13 | Cache Associativity 1 14 | Cache Block Size (bytes) 16 15 | Miss penalty (cyc) 30 16 | 17 | Simulation results: 18 | execution time 21857966 cycles 19 | instructions 5136716 20 | memory accesses 1957764 21 | overall miss rate 0.28 22 | read miss rate 0.30 23 | memory CPI 3.26 24 | total CPI 4.26 25 | average memory access time 8.54 cycles 26 | 27 | dirty evictions 60540 28 | load_misses 523277 29 | store_misses 30062 30 | load_hits 1208606 31 | store_hits 195819 32 | 33 | Example 2 34 | 35 | > gunzip -c traces/mcf.trace.gz | ./cachesim -a 8 -s 64 -l 32 -mp 42 36 | Cache parameters: 37 | Cache Size (KB) 64 38 | Cache Associativity 8 39 | Cache Block Size (bytes) 32 40 | Miss penalty (cyc) 42 41 | 42 | Simulation results: 43 | execution time 143963250 cycles 44 | instructions 19999998 45 | memory accesses 6943857 46 | overall miss rate 0.42 47 | read miss rate 0.36 48 | memory CPI 6.20 49 | total CPI 7.20 50 | average memory access time 17.85 cycles 51 | 52 | dirty evictions 995694 53 | load_misses 2036666 54 | store_misses 867426 55 | load_hits 3552806 56 | store_hits 486959 57 | -------------------------------------------------------------------------------- /cache.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int associativity = 2; // Associativity of cache 8 | int blocksize_bytes = 32; // Cache Block size in bytes 9 | int cachesize_kb = 64; // Cache size in KB 10 | int miss_penalty = 30; 11 | long tagSize = 1; 12 | 13 | void 14 | print_usage () 15 | { 16 | printf ("Usage: gunzip2 -c | ./cache -a assoc -l blksz -s size -mp mispen\n"); 17 | printf (" tracefile : The memory trace file\n"); 18 | printf (" -a assoc : The associativity of the cache\n"); 19 | printf (" -l blksz : The blocksize (in bytes) of the cache\n"); 20 | printf (" -s size : The size (in KB) of the cache\n"); 21 | printf (" -mp mispen: The miss penalty (in cycles) of a miss\n"); 22 | exit (0); 23 | } 24 | 25 | typedef struct cache 26 | { 27 | int valid; 28 | long tag[32]; 29 | int lru[32]; 30 | int dirty[32]; 31 | } cache; 32 | 33 | 34 | void hexToBin(char input[], char output[]) 35 | { 36 | int i; 37 | int size; 38 | size = strlen(input); 39 | 40 | for (i = 0; i < size; i++) 41 | { 42 | if (input[i] =='0') 43 | { 44 | output[i*4] = '0'; output[i*4+1] = '0'; output[i*4+2] = '0'; output[i*4+3] = '0'; 45 | } 46 | else if (input[i] =='1') 47 | { 48 | output[i*4] = '0'; output[i*4+1] = '0'; output[i*4+2] = '0'; output[i*4+3] = '1'; 49 | } 50 | else if (input[i] =='2') 51 | { 52 | output[i*4] = '0'; output[i*4+1] = '0'; output[i*4+2] = '1'; output[i*4+3] = '0'; 53 | } 54 | else if (input[i] =='3') 55 | { 56 | output[i*4] = '0'; output[i*4+1] = '0'; output[i*4+2] = '1'; output[i*4+3] = '1'; 57 | } 58 | else if (input[i] =='4') 59 | { 60 | output[i*4] = '0'; output[i*4+1] = '1'; output[i*4+2] = '0'; output[i*4+3] = '0'; 61 | } 62 | else if (input[i] =='5') 63 | { 64 | output[i*4] = '0'; output[i*4+1] = '1'; output[i*4+2] = '0'; output[i*4+3] = '1'; 65 | } 66 | else if (input[i] =='6') 67 | { 68 | output[i*4] = '0'; output[i*4+1] = '1'; output[i*4+2] = '1'; output[i*4+3] = '0'; 69 | } 70 | else if (input[i] =='7') 71 | { 72 | output[i*4] = '0'; output[i*4+1] = '1'; output[i*4+2] = '1'; output[i*4+3] = '1'; 73 | } 74 | else if (input[i] =='8') 75 | { 76 | output[i*4] = '1'; output[i*4+1] = '0'; output[i*4+2] = '0'; output[i*4+3] = '0'; 77 | } 78 | else if (input[i] =='9') 79 | { 80 | output[i*4] = '1'; output[i*4+1] = '0'; output[i*4+2] = '0'; output[i*4+3] = '1'; 81 | } 82 | else if (input[i] =='a') 83 | { 84 | output[i*4] = '1'; output[i*4+1] = '0'; output[i*4+2] = '1'; output[i*4+3] = '0'; 85 | } 86 | else if (input[i] =='b') 87 | { 88 | output[i*4] = '1'; output[i*4+1] = '0'; output[i*4+2] = '1'; output[i*4+3] = '1'; 89 | } 90 | else if (input[i] =='c') 91 | { 92 | output[i*4] = '1'; output[i*4+1] = '1'; output[i*4+2] = '0'; output[i*4+3] = '0'; 93 | } 94 | else if (input[i] =='d') 95 | { 96 | output[i*4] = '1'; output[i*4+1] = '1'; output[i*4+2] = '0'; output[i*4+3] = '1'; 97 | } 98 | else if (input[i] =='e') 99 | { 100 | output[i*4] = '1'; output[i*4+1] = '1'; output[i*4+2] = '1'; output[i*4+3] = '0'; 101 | } 102 | else if (input[i] =='f') 103 | { 104 | output[i*4] = '1'; output[i*4+1] = '1'; output[i*4+2] = '1'; output[i*4+3] = '1'; 105 | } 106 | } 107 | output[size*4] = '\0'; 108 | } 109 | 110 | 111 | int main(int argc, char * argv []) { 112 | 113 | long address; 114 | int loadstore, icount; 115 | char marker; 116 | long IC = 0; 117 | long programIC = 0; 118 | int i = 0; 119 | int j = 1; 120 | int dirty_eviction = 0; 121 | int load_hits = 0; 122 | int load_misses = 0; 123 | int store_hits = 0; 124 | int store_misses = 0; 125 | int load = 0; 126 | int store = 0; 127 | long et = 0; 128 | 129 | 130 | // Process the command line arguments 131 | while (j < argc) { 132 | if (strcmp ("-a", argv [j]) == 0) { 133 | j++; 134 | if (j >= argc) 135 | print_usage (); 136 | associativity = atoi (argv [j]); 137 | j++; 138 | } else if (strcmp ("-l", argv [j]) == 0) { 139 | j++; 140 | if (j >= argc) 141 | print_usage (); 142 | blocksize_bytes = atoi (argv [j]); 143 | j++; 144 | } else if (strcmp ("-s", argv [j]) == 0) { 145 | j++; 146 | if (j >= argc) 147 | print_usage (); 148 | cachesize_kb = atoi (argv [j]); 149 | j++; 150 | } else if (strcmp ("-mp", argv [j]) == 0) { 151 | j++; 152 | if (j >= argc) 153 | print_usage (); 154 | miss_penalty = atoi (argv [j]); 155 | j++; 156 | } else { 157 | print_usage (); 158 | } 159 | } 160 | 161 | // print out cache configuration 162 | printf("Cache parameters:\n"); 163 | printf ("Cache Size (KB)\t\t\t%d\n", cachesize_kb); 164 | printf ("Cache Associativity\t\t%d\n", associativity); 165 | printf ("Cache Block Size (bytes)\t%d\n", blocksize_bytes); 166 | printf ("Miss penalty (cyc)\t\t%d\n", miss_penalty); 167 | printf ("\n"); 168 | 169 | //Calculate the tag, index, block offset bits 170 | int blockOffsetBits = (int)(log(blocksize_bytes)/log(2)); 171 | int set = (int)((cachesize_kb*1024)/(blocksize_bytes*associativity)); 172 | int indexBits = (int)(log(set)/log(2)); 173 | int tagBits = 32 - indexBits - blockOffsetBits; 174 | 175 | char input[32]; 176 | char output[32]; 177 | char tagBin[32]; 178 | char index[32]; 179 | char blockOffset[32]; 180 | 181 | cache newCache[set]; 182 | 183 | //Initializing cache = null 184 | for (i=0; i < set; i++) 185 | { 186 | for (j=0; j (tagBits+index-1)]; 205 | for (i = 0; i=0; i--) 223 | { 224 | indexi = index[i] - '0'; 225 | indexDec = indexDec + (d*indexi); 226 | d = 2 * d; 227 | } 228 | 229 | //Convert tagBin to dec (tagDec) 230 | int tagDec = 0; 231 | int tagi = 0; 232 | d = 1; 233 | for (i= strlen(tagBin) - 1; i>=0; i--) 234 | { 235 | tagi = tagBin[i] - '0'; 236 | tagDec = tagDec + (d*tagi); 237 | d = 2 * d; 238 | } 239 | 240 | //Compare tag 241 | if (newCache[indexDec].valid == 0) 242 | { 243 | newCache[indexDec].valid = 1; 244 | newCache[indexDec].tag[0] = tagDec; 245 | newCache[indexDec].lru[0] = 0; 246 | 247 | et = et + miss_penalty; 248 | 249 | if (loadstore == 0) 250 | { 251 | //load 252 | load++; 253 | load_misses++; 254 | 255 | } else { 256 | //store 257 | store++; 258 | store_misses++; 259 | newCache[indexDec].dirty[0] = 1; 260 | } 261 | } 262 | else if (newCache[indexDec].valid == 1) 263 | { 264 | int hit = 0; 265 | for (i = 0; i