Advertisement
KDOXG

Simulador de Cache CPU

May 25th, 2019
661
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.07 KB | None | 0 0
  1. #include "hache.c"
  2.  
  3. void main()
  4. {
  5.     //Variaveis globais
  6.     int hits, accesses;
  7.     struct Miss misses;
  8.     float miss_rate;
  9.     struct Cache **cache;
  10.     int nsets = 256, bsize = 4, assoc = 1;
  11.     char policy;
  12.     FILE *input;
  13.  
  14.     /**--------------------- Inicialização
  15.      * O programa deverá receber como entrada uma string no seguinte formato:
  16.      *
  17.      * <politica_de_substituicao> <nsets_L1>:<bsize_L1>:<assoc_L1> arquivo_de_entrada
  18.      *
  19.      * Legenda:
  20.      * <nsets_L1>: quantidade de conjuntos para armazenar na cache. Valor padrão: 256
  21.      * <bsize_L1>: tamanho do bloco em bytes de cada endereço da cache. Valor padrão: 4
  22.      * <assoc_L1>: nível de associatividade dos conjuntos. Valor padrão: 1
  23.      * Caso os parâmetros inseridos não sejam números ou estejam vazios, o programa usará os valores padrões definidos anteriormente.
  24.      * (Para melhor aproveitamento do espaço da cache, sugerimos sempre usar números potências de 2.)
  25.      *
  26.      * <politica_de_substituicao>: configurar a política de substituição em caches associativas.
  27.      * Os macros suportados para configurar esta opção são:
  28.      * "LRU" - Least Recently Used: substitui o elemento do conjunto que foi chamado a mais tempo
  29.      * "LFU" - Least Frequently Used: substitui o elemento do conjunto que foi chamado menos vezes
  30.      * "FIFO" - First In, First Out: substitui o elemento do conjunto que foi inserido a mais tempo
  31.      * "LIFO" - Last In, First Out: substitui o elemento do conjunto que foi inserido a menos tempo
  32.      * "default" - usará a política de substituição padrão do programa, Random Replacement: substitui o elemento do conjunto escolhido aleatoriamente
  33.      * Se a associatividade for igual a 1 ou a palavra inserida não pertencer a estes macros, qualquer parâmetro inserido será ignorado e o programa usará a opção "default".
  34.      *
  35.      * arquivo_de_entrada: nome do arquivo de entrada que armazena todos os endereços divididos em 4 bytes para a simulação. Este nome não pode ser vazio.
  36.      *
  37.      * A saída será os valores passados pela string formatados para suas respectivas variáveis.
  38.     /*/
  39.  
  40.     /** Função:
  41.      * Inicializar todas as variáveis globais declaradas no topo.
  42.      * Depois, detectar se a string passada para input_init poderá ser formatada corretamente.
  43.      * Se for possível, extrair da string os números necessários para configurar a cache
  44.      * e o nome do arquivo para simulação.
  45.      */
  46.     Cache:
  47.     hits = 0;
  48.     accesses = 0;
  49.     misses.compulsory = 0;
  50.     misses.capacity = 0;
  51.     misses.conflict = 0;
  52.     nsets = 256;
  53.     bsize = 4;
  54.     assoc = 1;
  55.     policy = '\0';
  56.  
  57.     {
  58.         char *input_init = malloc(80*sizeof(char));
  59.         fgets(input_init, 80, stdin);
  60.  
  61.         if(strstr(input_init, "help") == input_init){
  62.             if(help(input_init) == 0)
  63.                 {
  64.                     free(input_init);
  65.                     goto Cache;
  66.                 }
  67.         }
  68.  
  69.         short int i, count_1=0, count_2=0, Error=0;
  70.         for (i=0; input_init[i] != '\0'; i++)
  71.         {
  72.             if (input_init[0] == ' ')
  73.                 Error = 1;
  74.             if (input_init[i] == ' ')
  75.                 count_1++;
  76.             if (count_1 == 1 && input_init[i] == ':')
  77.                 count_2++;
  78.             if (count_1 == 2 && (input_init[i+1] == '\0' || input_init[i+1] == '\n'))
  79.                 Error = 1;
  80.             if (count_1 == 2 && input_init[i+1] != '\0' && input_init[i+1] != '\n' && input_init[i+1] != ' ')
  81.                 break;
  82.         }
  83.         if (Error != 0 || count_1 != 2 || count_2 != 2)
  84.         {
  85.             printf("Erro: parâmetros passados de forma incorreta! Desligando...");
  86.             free(input_init);
  87.             return;
  88.         }
  89.         else
  90.             printf("\n");
  91.  
  92.         char *policy_aux, *nsets_aux, *bsize_aux, *assoc_aux, *input_file;
  93.         short int j=0, k=0;
  94.         policy_aux = input_init;
  95.         for (i=0; i<strlen(input_init); i++)
  96.         {
  97.             if (input_init[i] == ' ' && j == 0)
  98.             {
  99.                 input_init[i] = '\0';
  100.                 if (input_init[i+1] != ':')
  101.                     nsets_aux = input_init+i+1;
  102.                 else
  103.                     nsets_aux = NULL;
  104.  
  105.                 for (j=i+1; input_init[j] != ' '; j++)
  106.                 {
  107.                     if (input_init[j] == ':' && k == 0)
  108.                     {
  109.                         input_init[j] = '\0';
  110.                         if (input_init[j+1] != ':')
  111.                             bsize_aux = input_init+j+1;
  112.                         else
  113.                             bsize_aux = NULL;
  114.                         k=1;
  115.                     }
  116.                     if (input_init[j] == ':' && k == 1)
  117.                     {
  118.                         input_init[j] = '\0';
  119.                         if (input_init[j+1] != ' ')
  120.                             assoc_aux = input_init+j+1;
  121.                         else
  122.                             assoc_aux = NULL;
  123.                     }
  124.                 }
  125.                 input_init[j] = '\0';
  126.                 input_file = (input_init+j+1);
  127.                 for (k=0; input_init[k] != '\n'; k++);
  128.                 input_init[k] = '\0';
  129.                 break;
  130.             }
  131.         }
  132.  
  133.         if (strcmp(policy_aux,"LRU") == 0)
  134.             policy |= 1;
  135.         if (strcmp(policy_aux,"LFU") == 0)
  136.             policy |= 2;
  137.         if (strcmp(policy_aux,"FIFO") == 0)
  138.             policy |= 4;
  139.         if (strcmp(policy_aux,"LIFO") == 0)
  140.             policy |= 8;
  141.  
  142.         if (strcmp(nsets_aux,"eu") == 0 && strcmp(bsize_aux,"quero") == 0 && strcmp(assoc_aux,"hash") == 0)
  143.         {
  144.             free(input_init);
  145.             hache(); //Minha obra-prima!
  146.             goto Cache;
  147.         }
  148.  
  149.         int parametro_1=atoi(nsets_aux), parametro_2=atoi(bsize_aux), parametro_3=atoi(assoc_aux);
  150.         if (parametro_1 != 0)
  151.             nsets = parametro_1;
  152.         if (parametro_2 != 0)
  153.             bsize = parametro_2;
  154.         if (parametro_3 != 0)
  155.             assoc = parametro_3;
  156.         if (assoc == 1)
  157.             policy = '\0';
  158.  
  159.         input = fopen(input_file,"rb");
  160.  
  161.         free(input_init);
  162.         if (input == NULL)
  163.         {
  164.             printf("Erro: não foi possível ler o arquivo! Desligando...");
  165.             return;
  166.         }
  167.     }
  168.  
  169.     /** Função:
  170.      * Inicializar a matriz recém alocada que simulará a memória cache.
  171.      */
  172.     {
  173.         int i,j;
  174.         cache = malloc(assoc*sizeof(struct Cache*));
  175.         for (i=0; i<assoc; i++)
  176.         {
  177.             cache[i] = malloc(nsets*sizeof(struct Cache));
  178.             for (j=0; j<nsets; j++)
  179.             {
  180.                 cache[i][j].tag = 0;
  181.                 cache[i][j].policyControl = 0;
  182.                 cache[i][j].bit_valid = 0;
  183.             }
  184.         }
  185.     }
  186.  
  187.     /**--------------------- Execução
  188.      * O programa deverá receber uma série de valores de entrada, valores estes que serão os endereços procurados
  189.      * posteriormente na matriz criada pelo simulador na inicialização. Cada endereço será um número de 32 bits.
  190.      * A saída será a quantidade de hits e misses ocorridos.
  191.      */
  192.  
  193.     /** Função:
  194.      * Executará a simulação de buscas de endereços em uma cache de nível 1.
  195.      */
  196.     {
  197.         int tag, index,
  198.         b_offset = ceil(log2(bsize)), b_index = ceil(log2(nsets)),
  199.         i, file_count=0, cache_count=0;
  200.         Address address;
  201.  
  202.         while(fgetc(input) != EOF)
  203.         {
  204.             fseek(input,-1,SEEK_CUR);
  205.             fgets((char*)&address.a,5,input);
  206.             file_count += 4;
  207.             fseek(input,file_count,SEEK_SET);
  208.             tag = address.a >> (b_offset + b_index);
  209.             index = (address.a >> (b_offset)) & (int)(pow(2,b_index)-1);
  210.             for (i=0; i<assoc; i++)
  211.             {
  212.                 if (cache[i][index].bit_valid == 0)
  213.                 {
  214.                     cache[i][index].bit_valid = 1;
  215.                     cache[i][index].tag = tag;
  216.                     cache_count++;
  217.                     misses.compulsory++;
  218.                     setReplacement(cache,policy,i,assoc,index,0b00000010);
  219.                     break;
  220.                 }
  221.                 if (cache[i][index].tag == tag)
  222.                 {
  223.                     hits++;
  224.                     setReplacement(cache,policy,i,assoc,index,0b00000000);
  225.                     break;
  226.                 }
  227.             }
  228.  
  229.             if (i == assoc)
  230.             {
  231.  
  232.                 i = getReplacement(cache,policy,assoc,index);
  233.                 cache[i][index].tag = tag;
  234.                 setReplacement(cache,policy,i,assoc,index,0b00000001);
  235.                 if (cache_count == (nsets*assoc))
  236.                     misses.capacity++;
  237.                 else
  238.                     misses.conflict++;
  239.             }
  240.         }
  241.         accesses = misses.capacity + misses.compulsory + misses.conflict + hits;
  242.         miss_rate = 100 * (accesses-hits) / accesses;
  243.  
  244.         for (i=0; i<assoc; i++)
  245.             free(cache[i]);
  246.         free(cache);
  247.         fclose(input);
  248.     }
  249.  
  250.     /**--------------------- Finalização
  251.      * O programa exibirá um relatório sobre o acesso à memória.
  252.      */
  253.  
  254.     printf("########## SIMULADOR DE CPU CACHE ##########\nDesenvolvido por: Kevin S. Pereira (KDOXG) e Frederico P. Antunes\nTrabalho de Arquitetura e Organização de Computadores 2\nUniversidade Federal de Pelotas, 2019\n\n");
  255.  
  256.     printf("Tamanho da memória cache: %d bytes\n", nsets * bsize * assoc);
  257.     printf("Mapeamento: ");
  258.     if (assoc == 1)
  259.         printf("Direto\n");
  260.     else
  261.     {
  262.         if (nsets != 1)
  263.             printf("Conjunto Associativo de %d vias\n", assoc);
  264.         else
  265.             printf("Totalmente Associativo\n");
  266.         printf("Política de substituição: ");
  267.         while(1)
  268.         {///Acho que esta foi a maior POG da minha vida o_O'
  269.             if (policy >> 0 == 0)
  270.             {
  271.                 printf("Random Replacement (RR)\n");
  272.                 break;
  273.             }
  274.             if (policy >> 1 == 0)
  275.             {
  276.                 printf("Least Recently Used (LRU)\n");
  277.                 break;
  278.             }
  279.             if (policy >> 2 == 0)
  280.             {
  281.                 printf("Least Frequently Used (LFU)\n");
  282.                 break;
  283.             }
  284.             if (policy >> 3 == 0)
  285.             {
  286.                 printf("First In, First Out (FIFO)\n");
  287.                 break;
  288.             }
  289.             if (policy >> 4 == 0)
  290.             {
  291.                 printf("Last In, First Out (LIFO)\n");
  292.                 break;
  293.             }
  294.             break;
  295.         }
  296.     }
  297.     printf("Quantidade de acessos: %d\n", accesses);
  298.     printf("Hits: %d\n", hits);
  299.     printf("Misses: %d\n", misses.capacity + misses.compulsory + misses.conflict);
  300.     printf("Misses compulsórios: %d\n", misses.compulsory);
  301.     printf("Misses de conflito: %d\n", misses.conflict);
  302.     printf("Misses de capacidade: %d\n", misses.capacity);
  303.     printf("Taxa de miss: %.2f%%", miss_rate);
  304.     printf("\nPrograma encerrado corretamente! Reiniciando...\n\n");
  305.  
  306.     goto Cache;
  307. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement