Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <limits.h>
- #define CACHE_LINE_SIZE 16
- int cycles = 0;
- int relevant_cycles = 0;
- int hits = 0;
- int misses = 0;
- long assoc;
- int num_sets;
- int num_cache_lines;
- double hit_rate;
- // Struktur der Cache-Eintraege
- typedef struct cache_entry_t {
- unsigned int tag;
- unsigned int age;
- int is_set;
- } cache_entry_t;
- cache_entry_t * mycache;
- void cache_cycle(int adresse){
- int hit = 0;
- int lru = 1;
- relevant_cycles++; // Relevante Cycles hochzaehlen
- adresse >>= 4; // Offset wegwerfen
- int index = adresse % num_sets; // Index berechnen
- unsigned int tag = adresse / num_sets; // Tag berechnen
- printf("Set: %5d, Tag: %8d", index, tag);
- int i;
- // Prueft, ob der Zugriff ein Hit war
- for (i = 0; i < assoc; i++){
- if (mycache[index * assoc + i].is_set == 1 && tag == mycache[index * assoc + i].tag){
- mycache[index * assoc + i].age = relevant_cycles;
- hits++;
- printf(" Hit.");
- hit = 1;
- lru = 0; // Wenn der Zugriff ein Hit war, wird keine LRU-Verdraenung benoetigt
- break;
- }
- }
- // Falls der Zugriff kein Hit war, wird ueberprueft ob das Set noch eine leere Zeile hat.
- // Ist dies der Fall, wird der Zugriff eingetragen
- if (hit == 0){
- misses++;
- printf(" Miss.");
- for (i = 0; i < assoc; i++){
- if (mycache[index * assoc + i].is_set == 0){
- mycache[index * assoc + i].age = relevant_cycles;
- mycache[index * assoc + i].is_set = 1;
- mycache[index * assoc + i].tag = tag;
- lru = 0; // Wenn der Zugriff neu eingetragen wird, wird keine LRU-Verdraengung benoetigt
- break;
- }
- }
- }
- // Falls das Set keine leere Zeile mehr hat, wird der aelteste Eintrag LRU-verdraengt
- if (lru == 1){
- unsigned int oldest_age = UINT_MAX;
- int oldest_line;
- for (i = 0; i < assoc; i++){
- if (mycache[index * assoc + i].age < oldest_age){
- oldest_age = mycache[index * assoc + i].age;
- oldest_line = i;
- }
- }
- mycache[index * assoc + oldest_line].tag = tag;
- mycache[index * assoc + oldest_line].age = relevant_cycles;
- printf("\tEintrag wurde LRU-verdraengt.");
- }
- printf("\n");
- }
- int main(int argc, char *argv[]){
- if (argc != 5){
- printf("Bitte das Programm folgendermassen ausfuehren:\n./cachesim <Dateiname> <Groesse> <Assoziazivitaet> <Nutzungsart>\n");
- return EXIT_FAILURE;
- }
- char* name = argv[1];
- long cache_size = strtoul(argv[2], NULL, 10);
- assoc = strtoul(argv[3], NULL, 10);
- char usage = argv[4][0];
- if (cache_size % CACHE_LINE_SIZE != 0){
- printf("cache_size muss ein Vielfaches von 16 Bytes sein.\n");
- return EXIT_FAILURE;
- }
- if (assoc != 1 && assoc != 2 && assoc != 4 && assoc != 8){
- printf("Assoziativitaet muss 1, 2, 4 oder 8 sein.\n");
- return EXIT_FAILURE;
- }
- if (usage != 'D' && usage != 'I' && usage != 'U'){
- printf("Nutzungsart muss D, I oder U sein.\n");
- return EXIT_FAILURE;
- }
- num_cache_lines = cache_size / CACHE_LINE_SIZE;
- num_sets = num_cache_lines / assoc;
- printf("Simuliere Cache...\n\n");
- printf("cache_line_size: %d\ncache_lines: %d\nways: %ld\nsets: %d\n\n", CACHE_LINE_SIZE, num_cache_lines, assoc, num_sets);
- FILE* file = fopen(name, "r");
- if (file == NULL){
- printf("Fehler beim Oeffnen des tracefiles. Programm wird beendet.\n");
- return EXIT_FAILURE;
- }
- cache_entry_t mycache_tmp[num_sets * assoc];
- mycache = mycache_tmp;
- int i;
- for (i = 0; i < num_sets * assoc; i++){
- mycache[i].is_set = 0;
- mycache[i].age = 0;
- }
- int zugriffstyp;
- int adresse;
- // Liest die einzelnen Zeilen der Datei und traegt die Zugriffe ein (bei entsprechendem Zugriffstyp)
- while (fscanf(file, "%d %x\n", &zugriffstyp, &adresse) == 2){
- cycles++;
- switch (usage) {
- case 'U':
- cache_cycle(adresse);
- break;
- case 'D':
- if (zugriffstyp != 2)
- cache_cycle(adresse);
- break;
- case 'I':
- if (zugriffstyp == 2)
- cache_cycle(adresse);
- break;
- default:
- printf("Nutzungsart ungueltig. Programm wird beendet.\n");
- return EXIT_FAILURE;
- break;
- }
- }
- printf("\nGesamtzugriffe: %d, relevante Zugriffe: %d\n", cycles, relevant_cycles);
- hit_rate = (float)hits / relevant_cycles;
- printf("Hits: %d, Misses: %d, Hit-Rate: %f\n", hits, misses, hit_rate);
- fclose(file);
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement