Advertisement
Guest User

Untitled

a guest
Feb 1st, 2015
187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.10 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <fcntl.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <limits.h>
  7.  
  8. #define CACHE_LINE_SIZE 16
  9.  
  10. int cycles = 0;
  11. int relevant_cycles = 0;
  12. int hits = 0;
  13. int misses = 0;
  14. long assoc;
  15. int num_sets;
  16. int num_cache_lines;
  17. double hit_rate;
  18.  
  19. // Struktur der Cache-Eintraege
  20.  
  21. typedef struct cache_entry_t {
  22.     unsigned int tag;
  23.     unsigned int age;
  24.     int is_set;
  25. } cache_entry_t;
  26.  
  27. cache_entry_t * mycache;
  28.  
  29. void cache_cycle(int adresse){
  30.  
  31.     int hit = 0;
  32.     int lru = 1;
  33.  
  34.     relevant_cycles++; // Relevante Cycles hochzaehlen  
  35.     adresse >>= 4; // Offset wegwerfen
  36.    
  37.     int index = adresse % num_sets; // Index berechnen    
  38.     unsigned int tag = adresse / num_sets; // Tag berechnen
  39.  
  40.     printf("Set: %5d, Tag: %8d", index, tag);
  41.  
  42.     int i;
  43.  
  44.     // Prueft, ob der Zugriff ein Hit war
  45.  
  46.     for (i = 0; i < assoc; i++){
  47.         if (mycache[index * assoc + i].is_set == 1 && tag == mycache[index * assoc + i].tag){
  48.             mycache[index * assoc + i].age = relevant_cycles;
  49.             hits++;
  50.             printf(" Hit.");
  51.             hit = 1;
  52.             lru = 0; // Wenn der Zugriff ein Hit war, wird keine LRU-Verdraenung benoetigt
  53.             break;
  54.         }
  55.     }
  56.  
  57.     // Falls der Zugriff kein Hit war, wird ueberprueft ob das Set noch eine leere Zeile hat.
  58.     // Ist dies der Fall, wird der Zugriff eingetragen
  59.  
  60.     if (hit == 0){
  61.         misses++;
  62.         printf(" Miss.");
  63.         for (i = 0; i < assoc; i++){
  64.             if (mycache[index * assoc + i].is_set == 0){
  65.                 mycache[index * assoc + i].age = relevant_cycles;
  66.                 mycache[index * assoc + i].is_set = 1;
  67.                 mycache[index * assoc + i].tag = tag;
  68.                 lru = 0; // Wenn der Zugriff neu eingetragen wird, wird keine LRU-Verdraengung benoetigt
  69.                 break;
  70.             }
  71.         }
  72.     }
  73.  
  74.     // Falls das Set keine leere Zeile mehr hat, wird der aelteste Eintrag LRU-verdraengt
  75.  
  76.     if (lru == 1){
  77.         unsigned int oldest_age = UINT_MAX;
  78.         int oldest_line;
  79.         for (i = 0; i < assoc; i++){
  80.             if (mycache[index * assoc + i].age < oldest_age){
  81.                 oldest_age = mycache[index * assoc + i].age;
  82.                 oldest_line = i;
  83.             }
  84.         }
  85.         mycache[index * assoc + oldest_line].tag = tag;
  86.         mycache[index * assoc + oldest_line].age = relevant_cycles;
  87.         printf("\tEintrag wurde LRU-verdraengt.");
  88.     }
  89.  
  90.     printf("\n");
  91.  
  92. }
  93.  
  94. int main(int argc, char *argv[]){
  95.  
  96.     if (argc != 5){
  97.         printf("Bitte das Programm folgendermassen ausfuehren:\n./cachesim <Dateiname> <Groesse> <Assoziazivitaet> <Nutzungsart>\n");
  98.         return EXIT_FAILURE;
  99.     }
  100.    
  101.     char* name = argv[1];
  102.     long cache_size = strtoul(argv[2], NULL, 10);
  103.     assoc = strtoul(argv[3], NULL, 10);
  104.     char usage = argv[4][0];
  105.    
  106.     if (cache_size % CACHE_LINE_SIZE != 0){
  107.         printf("cache_size muss ein Vielfaches von 16 Bytes sein.\n");
  108.         return EXIT_FAILURE;
  109.     }
  110.    
  111.     if (assoc != 1 && assoc != 2 && assoc != 4 && assoc != 8){
  112.         printf("Assoziativitaet muss 1, 2, 4 oder 8 sein.\n");
  113.         return EXIT_FAILURE;
  114.     }
  115.    
  116.     if (usage != 'D' && usage != 'I' && usage != 'U'){
  117.         printf("Nutzungsart muss D, I oder U sein.\n");
  118.         return EXIT_FAILURE;
  119.     }
  120.    
  121.     num_cache_lines = cache_size / CACHE_LINE_SIZE;
  122.     num_sets = num_cache_lines / assoc;
  123.    
  124.     printf("Simuliere Cache...\n\n");
  125.     printf("cache_line_size: %d\ncache_lines: %d\nways: %ld\nsets: %d\n\n", CACHE_LINE_SIZE, num_cache_lines, assoc, num_sets);
  126.      
  127.     FILE* file = fopen(name, "r");
  128.     if (file == NULL){
  129.         printf("Fehler beim Oeffnen des tracefiles. Programm wird beendet.\n");
  130.         return EXIT_FAILURE;
  131.     }
  132.    
  133.     cache_entry_t mycache_tmp[num_sets * assoc];
  134.     mycache = mycache_tmp;
  135.  
  136.     int i;
  137.  
  138.     for (i = 0; i < num_sets * assoc; i++){
  139.         mycache[i].is_set = 0;
  140.         mycache[i].age = 0;
  141.     }
  142.    
  143.     int zugriffstyp;
  144.     int adresse;
  145.    
  146.     // Liest die einzelnen Zeilen der Datei und traegt die Zugriffe ein (bei entsprechendem Zugriffstyp)
  147.  
  148.     while (fscanf(file, "%d %x\n", &zugriffstyp, &adresse) == 2){
  149.         cycles++;
  150.        
  151.         switch (usage) {
  152.             case 'U':
  153.                 cache_cycle(adresse);
  154.             break;
  155.            
  156.             case 'D':
  157.                 if (zugriffstyp != 2)
  158.                     cache_cycle(adresse);
  159.             break;
  160.            
  161.             case 'I':
  162.                 if (zugriffstyp == 2)
  163.                     cache_cycle(adresse);
  164.             break;
  165.            
  166.             default:
  167.                 printf("Nutzungsart ungueltig. Programm wird beendet.\n");
  168.                 return EXIT_FAILURE;
  169.             break;  
  170.         }    
  171.     }
  172.  
  173.     printf("\nGesamtzugriffe: %d, relevante Zugriffe: %d\n", cycles, relevant_cycles);
  174.    
  175.     hit_rate = (float)hits / relevant_cycles;
  176.     printf("Hits: %d, Misses: %d, Hit-Rate: %f\n", hits, misses, hit_rate);  
  177.    
  178.     fclose(file);
  179.  
  180.     return EXIT_SUCCESS;
  181. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement