Advertisement
Guest User

Untitled

a guest
Nov 21st, 2017
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.48 KB | None | 0 0
  1. /***************************************************************************
  2.  * *    Inf2C-CS Coursework 2: TLB and Cache Simulation
  3.  * *
  4.  * *    Instructor: Boris Grot
  5.  * *
  6.  * *    TA: Priyank Faldu
  7.  ***************************************************************************/
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <assert.h>
  13. #include <inttypes.h>
  14. #include <math.h>
  15. /* Do not add any more header files */
  16.  
  17. /*
  18.  * Various structures
  19.  */
  20. typedef enum {tlb_only, cache_only, tlb_cache} hierarchy_t;
  21. typedef enum {instruction, data} access_t;
  22. const char* get_hierarchy_type(uint32_t t) {
  23.     switch(t) {
  24.         case tlb_only: return "tlb_only";
  25.         case cache_only: return "cache-only";
  26.         case tlb_cache: return "tlb+cache";
  27.         default: assert(0); return "";
  28.     };
  29.     return "";
  30. }
  31.  
  32. typedef struct {
  33.     uint32_t address;
  34.     access_t accesstype;
  35. } mem_access_t;
  36.  
  37. // These are statistics for the cache and TLB and should be maintained by you.
  38. typedef struct {
  39.     uint32_t tlb_data_hits;
  40.     uint32_t tlb_data_misses;
  41.     uint32_t tlb_instruction_hits;
  42.     uint32_t tlb_instruction_misses;
  43.     uint32_t cache_data_hits;
  44.     uint32_t cache_data_misses;
  45.     uint32_t cache_instruction_hits;
  46.     uint32_t cache_instruction_misses;
  47. } result_t;
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56. /*
  57.  * Parameters for TLB and cache that will be populated by the provided code skeleton.
  58.  */
  59. hierarchy_t hierarchy_type = tlb_cache;
  60. uint32_t number_of_tlb_entries = 0;
  61. uint32_t page_size = 0;
  62. uint32_t number_of_cache_blocks = 0;
  63. uint32_t cache_block_size = 0;
  64. uint32_t num_page_table_accesses = 0;
  65.  
  66.  
  67. /*
  68.  * Each of the variables (subject to hierarchy_type) below must be populated by you.
  69.  */
  70. uint32_t g_total_num_virtual_pages = 0;
  71. uint32_t g_num_tlb_tag_bits = 0;
  72. uint32_t g_tlb_offset_bits = 0;
  73. uint32_t g_num_cache_tag_bits = 0;
  74. uint32_t g_cache_offset_bits= 0;
  75. result_t g_result;
  76.  
  77. /* Reads a memory access from the trace file and returns
  78.  * 1) access type (instruction or data access)
  79.  * 2) 32-bit virtual memory address
  80.  */
  81. mem_access_t read_transaction(FILE *ptr_file) {
  82.     char buf[1002];
  83.     char* token = NULL;
  84.     char* string = buf;
  85.     mem_access_t access;
  86.  
  87.     if (fgets(buf, 1000, ptr_file)!=NULL) {
  88.  
  89.         /* Get the access type */
  90.         token = strsep(&string, " \n");
  91.         if (strcmp(token,"I") == 0) {
  92.             access.accesstype = instruction;
  93.         } else if (strcmp(token,"D") == 0) {
  94.             access.accesstype = data;
  95.         } else {
  96.             printf("Unkown access type\n");
  97.             exit(-1);
  98.         }
  99.  
  100.         /* Get the address */
  101.         token = strsep(&string, " \n");
  102.         access.address = (uint32_t)strtol(token, NULL, 16);
  103.  
  104.         return access;
  105.     }
  106.  
  107.     /* If there are no more entries in the file return an address 0 */
  108.     access.address = 0;
  109.     return access;
  110. }
  111.  
  112. /*
  113.  * Call this function to get the physical page number for a given virtual number.
  114.  * Note that this function takes virtual page number as an argument and not the whole virtual address.
  115.  * Also note that this is just a dummy function for mimicing translation. Real systems maintains multi-level page tables.
  116.  */
  117. uint32_t dummy_translate_virtual_page_num(uint32_t virtual_page_num) {
  118.     uint32_t physical_page_num = virtual_page_num ^ 0xFFFFFFFF;
  119.     num_page_table_accesses++;
  120.     if ( page_size == 256 ) {
  121.         physical_page_num = physical_page_num & 0x00FFF0FF;
  122.     } else {
  123.         assert(page_size == 4096);
  124.         physical_page_num = physical_page_num & 0x000FFF0F;
  125.     }
  126.     return physical_page_num;
  127. }
  128.  
  129. void print_statistics(uint32_t num_virtual_pages, uint32_t num_tlb_tag_bits, uint32_t tlb_offset_bits, uint32_t num_cache_tag_bits, uint32_t cache_offset_bits, result_t* r) {
  130.     /* Do Not Modify This Function */
  131.  
  132.     printf("NumPageTableAccesses:%u\n", num_page_table_accesses);
  133.     printf("TotalVirtualPages:%u\n", num_virtual_pages);
  134.     if ( hierarchy_type != cache_only ) {
  135.         printf("TLBTagBits:%u\n", num_tlb_tag_bits);
  136.         printf("TLBOffsetBits:%u\n", tlb_offset_bits);
  137.         uint32_t tlb_total_hits = r->tlb_data_hits + r->tlb_instruction_hits;
  138.         uint32_t tlb_total_misses = r->tlb_data_misses + r->tlb_instruction_misses;
  139.         printf("TLB:Accesses:%u\n", tlb_total_hits + tlb_total_misses);
  140.         printf("TLB:data-hits:%u, data-misses:%u, inst-hits:%u, inst-misses:%u\n", r->tlb_data_hits, r->tlb_data_misses, r->tlb_instruction_hits, r->tlb_instruction_misses);
  141.         printf("TLB:total-hit-rate:%2.2f%%\n", tlb_total_hits / (float)(tlb_total_hits + tlb_total_misses) * 100.0);
  142.     }
  143.  
  144.     if ( hierarchy_type != tlb_only ) {
  145.         printf("CacheTagBits:%u\n", num_cache_tag_bits);
  146.         printf("CacheOffsetBits:%u\n", cache_offset_bits);
  147.         uint32_t cache_total_hits = r->cache_data_hits + r->cache_instruction_hits;
  148.         uint32_t cache_total_misses = r->cache_data_misses + r->cache_instruction_misses;
  149.         printf("Cache:data-hits:%u, data-misses:%u, inst-hits:%u, inst-misses:%u\n", r->cache_data_hits, r->cache_data_misses, r->cache_instruction_hits, r->cache_instruction_misses);
  150.         printf("Cache:total-hit-rate:%2.2f%%\n", cache_total_hits / (float)(cache_total_hits + cache_total_misses) * 100.0);
  151.     }
  152. }
  153.  
  154. //Creating cache_lines struct
  155. typedef struct {
  156.   int validBit;
  157.   uint32_t tag;
  158.   int index;
  159.   uint32_t data;
  160. } cache_lines;
  161.  
  162. /*
  163.  *
  164.  * Add any global variables and/or functions here as you wish.
  165.  *
  166.  */
  167.  
  168. cache_lines * direct_map_cache;
  169.  
  170.  
  171. void directMapping(uint32_t physicalAddress, access_t type) {
  172.  
  173.    int indexSize, offsetSize, tagSize;
  174.  
  175.  
  176.    switch (number_of_cache_blocks) {
  177.      case 256:
  178.         indexSize = 8;
  179.     default:
  180.           indexSize = 11;
  181.    }
  182.  
  183.    switch (cache_block_size) {
  184.      case 32:
  185.         offsetSize = 5;
  186.     default:
  187.         offsetSize= 6;
  188.    }
  189.  
  190.    tagSize = 32 - indexSize - offsetSize;
  191.  
  192.   uint32_t getTag = physicalAddress >> (32-tagSize);
  193.   uint32_t getIndex = physicalAddress << tagSize  >> (32 - indexSize);
  194.   uint32_t getOffset = physicalAddress << (getTag+getIndex);
  195.  
  196.   if (direct_map_cache[getIndex].tag == getTag && direct_map_cache[getIndex].validBit) {
  197.     if ( type == data) {
  198.       g_result.cache_data_hits++;
  199.     } else {
  200.       g_result.cache_instruction_hits++;
  201.     }
  202.   } else {
  203.     if ( type == data) {
  204.       g_result.cache_data_misses++;
  205.     } else {
  206.       g_result.cache_instruction_misses++;
  207.     }
  208.   }
  209.  
  210.   direct_map_cache[getIndex].validBit = 1;
  211.   direct_map_cache[getIndex].data = 0;
  212.   direct_map_cache[getIndex].tag = getTag;
  213.  
  214. }
  215.  
  216.  
  217.  
  218.  
  219.  
  220. int main(int argc, char** argv) {
  221.  
  222.     /*
  223.      *
  224.      * Read command-line parameters and initialize configuration variables.
  225.      *
  226.      */
  227.     int improper_args = 0;
  228.     char file[10000];
  229.     if ( argc < 2 ) {
  230.         improper_args = 1;
  231.         printf("Usage: ./mem_sim [hierarchy_type: tlb-only cache-only tlb+cache] [number_of_tlb_entries: 8/16] [page_size: 256/4096] [number_of_cache_blocks: 256/2048] [cache_block_size: 32/64] mem_trace.txt\n");
  232.     } else  {
  233.         /* argv[0] is program name, parameters start with argv[1] */
  234.         if ( strcmp(argv[1], "tlb-only") == 0 ) {
  235.             if ( argc != 5 ) {
  236.                 improper_args = 1;
  237.                 printf("Usage: ./mem_sim tlb-only [number_of_tlb_entries: 8/16] [page_size: 256/4096] mem_trace.txt\n");
  238.             } else {
  239.                 hierarchy_type = tlb_only;
  240.                 number_of_tlb_entries = atoi(argv[2]);
  241.                 page_size = atoi(argv[3]);
  242.                 strcpy(file, argv[4]);
  243.             }
  244.         } else if ( strcmp(argv[1], "cache-only") == 0 ) {
  245.             if ( argc != 6 ) {
  246.                 improper_args = 1;
  247.                 printf("Usage: ./mem_sim cache-only [page_size: 256/4096] [number_of_cache_blocks: 256/2048] [cache_block_size: 32/64] mem_trace.txt\n");
  248.             } else {
  249.                 hierarchy_type = cache_only;
  250.                 page_size = atoi(argv[2]);
  251.                 number_of_cache_blocks = atoi(argv[3]);
  252.                 cache_block_size = atoi(argv[4]);
  253.                 strcpy(file, argv[5]);
  254.             }
  255.         } else if ( strcmp(argv[1], "tlb+cache") == 0 ) {
  256.             if ( argc != 7 ) {
  257.                 improper_args = 1;
  258.                 printf("Usage: ./mem_sim tlb+cache [number_of_tlb_entries: 8/16] [page_size: 256/4096] [number_of_cache_blocks: 256/2048] [cache_block_size: 32/64] mem_trace.txt\n");
  259.             } else {
  260.                 hierarchy_type = tlb_cache;
  261.                 number_of_tlb_entries = atoi(argv[2]);
  262.                 page_size = atoi(argv[3]);
  263.                 number_of_cache_blocks = atoi(argv[4]);
  264.                 cache_block_size = atoi(argv[5]);
  265.                 strcpy(file, argv[6]);
  266.             }
  267.         } else {
  268.             printf("Unsupported hierarchy type: %s\n", argv[1]);
  269.             improper_args = 1;
  270.         }
  271.     }
  272.     if ( improper_args ) {
  273.         exit(-1);
  274.     }
  275.     assert(page_size == 256 || page_size == 4096);
  276.     if ( hierarchy_type != cache_only) {
  277.         assert(number_of_tlb_entries == 8 || number_of_tlb_entries == 16);
  278.     }
  279.     if ( hierarchy_type != tlb_only) {
  280.         assert(number_of_cache_blocks == 256 || number_of_cache_blocks == 2048);
  281.         assert(cache_block_size == 32 || cache_block_size == 64);
  282.     }
  283.  
  284.     printf("input:trace_file: %s\n", file);
  285.     printf("input:hierarchy_type: %s\n", get_hierarchy_type(hierarchy_type));
  286.     printf("input:number_of_tlb_entries: %u\n", number_of_tlb_entries);
  287.     printf("input:page_size: %u\n", page_size);
  288.     printf("input:number_of_cache_blocks: %u\n", number_of_cache_blocks);
  289.     printf("input:cache_block_size: %u\n", cache_block_size);
  290.     printf("\n");
  291.  
  292.     /* Open the file mem_trace.txt to read memory accesses */
  293.     FILE *ptr_file;
  294.     ptr_file =fopen(file,"r");
  295.     if (!ptr_file) {
  296.         printf("Unable to open the trace file: %s\n", file);
  297.         exit(-1);
  298.     }
  299.  
  300.     /* result structure is initialized for you. */
  301.     memset(&g_result, 0, sizeof(result_t));
  302.  
  303.     /* Do not delete any of the lines below.
  304.      * Use the following snippet and add your code to finish the task. */
  305.  
  306.     /* You may want to setup your TLB and/or Cache structure here. */
  307.  
  308.     direct_map_cache =  (cache_lines*) malloc (number_of_cache_blocks);
  309.  
  310.     mem_access_t access;
  311.     /* Loop until the whole trace file has been read. */
  312.     while(1) {
  313.         access = read_transaction(ptr_file);
  314.         // If no transactions left, break out of loop.
  315.         if (access.address == 0)
  316.             break;
  317.         /* Add your code here */
  318.         /* Feed the address to your TLB and/or Cache simulator and collect statistics. */
  319.  
  320.  
  321.  
  322.       int numberOfOffsetBits;
  323.       if (hierarchy_type == cache_only) {
  324.         if (page_size == 4096) {
  325.           numberOfOffsetBits=12;
  326.         }
  327.         else {
  328.           numberOfOffsetBits=8;
  329.         }
  330.         uint32_t physicalPageNum = dummy_translate_virtual_page_num(access.address >> numberOfOffsetBits);
  331.         uint32_t actualPhysicalAddress = physicalPageNum << numberOfOffsetBits | (access.address << (32-numberOfOffsetBits) >> (32-numberOfOffsetBits));
  332.         directMapping(actualPhysicalAddress, access.accesstype);
  333.       }
  334.  
  335.     }
  336.  
  337.     /* Do not modify code below. */
  338.     /* Make sure that all the parameters are appropriately populated. */
  339.     print_statistics(g_total_num_virtual_pages, g_num_tlb_tag_bits, g_tlb_offset_bits, g_num_cache_tag_bits, g_cache_offset_bits, &g_result);
  340.  
  341.     /* Close the trace file. */
  342.     fclose(ptr_file);
  343.     return 0;
  344. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement