2010-05-03 9 views
8

Ok, esta es solo mi segunda pregunta, y es bastante tonta. Es para una tarea escolar, pero nadie (incluidos los TA) parece poder ayudarme. Es un poco difícil, pero no estoy seguro de a quién más recurrir.Simulador de caché en C

Esencialmente la tarea era hacer un simulador de caché. Esta versión es un mapeo directo y en realidad es solo una pequeña parte de todo el proyecto, pero si no puedo resolverlo no tengo ninguna posibilidad con otras asociaciones. Estoy publicando todo el código porque no quiero hacer ninguna suposición sobre dónde está el problema.

Este es el caso de prueba:

y se ejecuta el siguiente comando:
./sims 512 32 FIFO directa en peso pinatrace.out

Se supone que para obtener:

hits: 604037 
misses 138349 
writes: 239269 
reads: 138349 

pero me sale:

Hits: 587148 
Misses: 155222 
Writes: 239261 
Reads: 155222 

Si alguien pudiera al menos apuntarme en la dirección correcta, sería muy apreciado. Estuve atascado en esto por alrededor de 12 horas.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <math.h> 


struct myCache 
{ 
    int valid; 
    char *tag; 
    char *block; 
}; 

/* 
sim [-h] <cache size> <associativity> <block size> <replace alg> <write policy> 
<trace file> 
*/ 

//God willing I come up with a better Hex to Bin convertion that maintains the beginning 0s... 
void hex2bin(char input[], char output[]) 
{ 
    int i; 
    int a = 0; 
    int b = 1; 
    int c = 2; 
    int d = 3; 
    int x = 4; 
    int size; 
    size = strlen(input); 

    for (i = 0; i < size; i++) 
    { 
     if (input[i] =='0') 
     { 
      output[i*x +a] = '0'; 
      output[i*x +b] = '0'; 
      output[i*x +c] = '0'; 
      output[i*x +d] = '0'; 
     } 
     else if (input[i] =='1') 
     { 
      output[i*x +a] = '0'; 
      output[i*x +b] = '0'; 
      output[i*x +c] = '0'; 
      output[i*x +d] = '1'; 
     }  
     else if (input[i] =='2') 
     { 
      output[i*x +a] = '0'; 
      output[i*x +b] = '0'; 
      output[i*x +c] = '1'; 
      output[i*x +d] = '0'; 
     }  
     else if (input[i] =='3') 
     { 
      output[i*x +a] = '0'; 
      output[i*x +b] = '0'; 
      output[i*x +c] = '1'; 
      output[i*x +d] = '1'; 
     }  
     else if (input[i] =='x') 
     { 
      output[i*x +a] = '0'; 
      output[i*x +b] = '1'; 
      output[i*x +c] = '0'; 
      output[i*x +d] = '0'; 
     }  
     else if (input[i] =='5') 
     { 
      output[i*x +a] = '0'; 
      output[i*x +b] = '1'; 
      output[i*x +c] = '0'; 
      output[i*x +d] = '1'; 
     }  
     else if (input[i] =='6') 
     { 
      output[i*x +a] = '0'; 
      output[i*x +b] = '1'; 
      output[i*x +c] = '1'; 
      output[i*x +d] = '0'; 
     }  
     else if (input[i] =='7') 
     { 
      output[i*x +a] = '0'; 
      output[i*x +b] = '1'; 
      output[i*x +c] = '1'; 
      output[i*x +d] = '1'; 
     }  
     else if (input[i] =='8') 
     { 
      output[i*x +a] = '1'; 
      output[i*x +b] = '0'; 
      output[i*x +c] = '0'; 
      output[i*x +d] = '0'; 
     } 
     else if (input[i] =='9') 
     { 
      output[i*x +a] = '1'; 
      output[i*x +b] = '0'; 
      output[i*x +c] = '0'; 
      output[i*x +d] = '1'; 
     } 
     else if (input[i] =='a') 
     {  
      output[i*x +a] = '1'; 
      output[i*x +b] = '0'; 
      output[i*x +c] = '1'; 
      output[i*x +d] = '0'; 
     } 
     else if (input[i] =='b') 
     { 
      output[i*x +a] = '1'; 
      output[i*x +b] = '0'; 
      output[i*x +c] = '1'; 
      output[i*x +d] = '1'; 
     } 
     else if (input[i] =='c') 
     { 
      output[i*x +a] = '1'; 
      output[i*x +b] = '1'; 
      output[i*x +c] = '0'; 
      output[i*x +d] = '0'; 
     } 
     else if (input[i] =='d') 
     {  
      output[i*x +a] = '1'; 
      output[i*x +b] = '1'; 
      output[i*x +c] = '0'; 
      output[i*x +d] = '1'; 
     } 
     else if (input[i] =='e') 
     {  
      output[i*x +a] = '1'; 
      output[i*x +b] = '1'; 
      output[i*x +c] = '1'; 
      output[i*x +d] = '0'; 
     } 
     else if (input[i] =='f') 
     { 
      output[i*x +a] = '1'; 
      output[i*x +b] = '1'; 
      output[i*x +c] = '1'; 
      output[i*x +d] = '1'; 
     } 
    } 

    output[32] = '\0'; 
} 




int main(int argc, char* argv[]) 
{  
    FILE *tracefile; 
    char readwrite; 
    int trash; 
    int cachesize; 
    int blocksize; 
    int setnumber; 
    int blockbytes; 
    int setbits; 
    int blockbits; 
    int tagsize; 
    int m; 
    int count = 0; 
    int count2 = 0; 
    int count3 = 0; 
    int i; 
    int j; 
    int xindex; 
    int jindex; 
    int kindex; 
    int lindex;  
    int setadd; 
    int totalset; 
    int writeMiss = 0; 
    int writeHit = 0; 
    int cacheMiss = 0; 
    int cacheHit = 0; 
    int read = 0; 
    int write = 0; 
    int size; 
    int extra; 

    char bbits[100]; 
    char sbits[100]; 
    char tbits[100]; 
    char output[100]; 
    char input[100]; 
    char origtag[100]; 


    if (argc != 7) 
    { 
     if (strcmp(argv[0], "-h")) 
     { 
      printf("./sim2 <cache size> <associativity> <block size> <replace alg> <write policy> <trace file>\n"); 
      return 0; 
     } 
     else 
     { 
      fprintf(stderr, "Error: wrong number of parameters.\n"); 
      return -1; 
     } 
    } 

    tracefile = fopen(argv[6], "r"); 

    if(tracefile == NULL) 
    { 
     fprintf(stderr, "Error: File is NULL.\n"); 
     return -1; 
    } 

    //Determining size of sbits, bbits, and tag 
    cachesize = atoi(argv[1]); 
    blocksize = atoi(argv[3]); 
    setnumber = (cachesize/blocksize); 
    printf("setnumber: %d\n", setnumber); 
    setbits = (round((log(setnumber))/(log(2)))); 
    printf("sbits: %d\n", setbits); 
    blockbits = log(blocksize)/log(2); 
    printf("bbits: %d\n", blockbits); 
    tagsize = 32 - (blockbits + setbits); 
    printf("t: %d\n", tagsize); 

    struct myCache newCache[setnumber]; 

    //Allocating Space for Tag Bits, initiating tag and valid to 0s 
    for(i=0;i<setnumber;i++) 
    { 
     newCache[i].tag = (char *)malloc(sizeof(char)*(tagsize+1)); 
     for(j=0;j<tagsize;j++) 
     { 
      newCache[i].tag[j] = '0'; 
     } 
     newCache[i].valid = 0; 
    } 

    while(fgetc(tracefile)!='#') 
    {  
     setadd = 0; 
     totalset = 0; 
     //read in file 
     fseek(tracefile,-1,SEEK_CUR); 
     fscanf(tracefile, "%x: %c %s\n", &trash, &readwrite, origtag); 

     //shift input Hex 
     size = strlen(origtag); 
     extra = (10 - size); 
     for(i=0; i<extra; i++) 
      input[i] = '0'; 

     for(i=extra, j=0; i<(size-(2-extra)); j++, i++) 
      input[i]=origtag[j+2]; 

     input[8] = '\0'; 

     // Convert Hex to Binary 
     hex2bin(input, output); 

     //Resolving the Address into tbits, sbits, bbits 
     for (xindex=0, jindex=(32-blockbits); jindex<32; jindex++, xindex++) 
    { 
      bbits[xindex] = output[jindex]; 
     } 
    bbits[xindex]='\0'; 

    for (xindex=0, kindex=(32-(blockbits+setbits)); kindex<32-(blockbits); kindex++, xindex++){ 
     sbits[xindex] = output[kindex]; 
    } 
    sbits[xindex]='\0'; 

    for (xindex=0, lindex=0; lindex<(32-(blockbits+setbits)); lindex++, xindex++){ 
     tbits[xindex] = output[lindex]; 
    } 
    tbits[xindex]='\0'; 

    //Convert set bits from char array into ints 
    for(xindex = 0, kindex = (setbits -1); xindex < setbits; xindex ++, kindex--) 
     { 
      if (sbits[xindex] == '1') 
       setadd = 1; 
      if (sbits[xindex] == '0') 
       setadd = 0; 
      setadd = setadd * pow(2, kindex); 
      totalset += setadd; 
     } 

     //Calculating Hits and Misses 
     if (newCache[totalset].valid == 0) 
     { 
      newCache[totalset].valid = 1; 
      strcpy(newCache[totalset].tag, tbits); 
     } 

     else if (newCache[totalset].valid == 1) 
     { 
      if(strcmp(newCache[totalset].tag, tbits) == 0) 
      { 
       if (readwrite == 'W') 
       { 
        cacheHit++;   
        write++; 
       } 
       if (readwrite == 'R') 
        cacheHit++;  
      } 
      else 
      { 
       if (readwrite == 'R') 
       { 
        cacheMiss++; 
        read++; 
       } 
       if (readwrite == 'W') 
       { 
        cacheMiss++; 
        read++; 
        write++; 
       } 
       strcpy(newCache[totalset].tag, tbits); 
      } 
     }   
    } 
    printf("Hits: %d\n", cacheHit); 
    printf("Misses: %d\n", cacheMiss); 
    printf("Writes: %d\n", write); 
    printf("Reads: %d\n", read); 
} 
+0

PD: He intentado tan duro para hacer esta lectura de acuerdo con el formato aquí. Lo siento si todavía hace que tus ojos sangren! – DuffDuff

+2

No debería 'else if (input [i] == 'x')' en 'hex2bin' be' input [i] == '4''? –

+2

El hecho de que su TA no pueda resolverlo no significa que la respuesta está totalmente más allá de sus capacidades. Él puede conocer el tema mejor que usted, pero ** usted ** conoce su código mejor que él, y ** usted ** necesita aprender a resolver lo que está mal por su cuenta. –

Respuesta

4

Tienes dos problemas. En primer lugar, Scott Wales tiene razón sobre su función hex2bin(); tiene un 'x', donde quiere decir '4'.

En segundo lugar, no está contando correctamente una falta de caché cuando se golpea una ranura de caché no válida. Simplemente puede manejar "inválida" con exactamente la misma ruta de código que utiliza para una señorita:

if ((newCache[totalset].valid == 1) && (strcmp(newCache[totalset].tag, tbits) == 0)) 
    { 
     /* Hit */ 
     if (readwrite == 'W') 
     { 
      cacheHit++; 
      write++; 
     } 
     if (readwrite == 'R') 
      cacheHit++; 
    } 
    else 
    { 
     /* Miss (cache entry invalid, or wrong tag) */ 
     if (readwrite == 'R') 
     { 
      cacheMiss++; 
      read++; 
     } 
     if (readwrite == 'W') 
     { 
      cacheMiss++; 
      read++; 
      write++; 
     } 
     newCache[totalset].valid = 1; 
     strcpy(newCache[totalset].tag, tbits); 
    } 
+0

Wow gracias. Originalmente había estado agregando mis errores de esa manera, pero como eran demasiado altos para empezar, los reduje eliminando ese código. No puedo creer que esto haya sido (casi todo) debido a esa estúpida 'x'. /avergonzada. – DuffDuff