2017-05-10 5 views
-1

Ich schreibe eine C-Funktion, um einen Cache mit einem Adress-Trace zu simulieren. Die Funktion funktioniert wie erwartet, wenn sie auf meinem Mac mit gcc (wirklich clang) kompiliert wird. diese gcc --version auf meinem Mac kehrt:Unterschied im Verhalten zwischen clang und gcc?

Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 
Apple LLVM version 8.1.0 (clang-802.0.42) 

Wenn ich das gleiche Programm unter Linux mit gcc kompilieren, sind die Erträge weg, und eC & hC in meinem Programm (Cache-Räumung Zähler und hit counter) sind in den Hunderten Tausende, wenn sie unter 10 sein sollte, wenn gcc --version auf dem linux-Rechner eingeben, es gibt diese:

gcc (Ubuntu 4.9.3-8ubuntu2 ~ 14,04) 4.9.3

Hier ist die Programm:

#include <stdio.h> 
    #include <stdlib.h> 
    #include <string.h> 
    #include <math.h> 
    #include <limits.h> 
    #include <getopt.h> 
    #include "cachelab.h" 

    typedef struct{ 
     int v; 
     int t; 
     int LRU; 
    } block; 

    typedef struct{ 
     block *blocks; 
    } set; 

    typedef struct{ 
     set *sets; 
    } cache; 

    void simulate(int s, int E, int b, char* file, int* hC, int* mC, int* eC) 
    { 
     int numSets = (1 << s); 
     char operation; 
     int address; 
     int size; 
     int curTag; 
     int curSet; 
     int maxLRU = 0; 
     int curLRU = 0; 
     int check = 0; 

    cache c; 
    set *sets = malloc(sizeof(set) * numSets); 
    c.sets = sets; 

    int i = 0; 
    while(i < numSets) 
    { 
     c.sets[i].blocks = malloc(sizeof(block) * E); 
     for (int j = 0; j < E; j++) 
     { 
      c.sets[i].blocks[j].v = 0; 
      c.sets[i].blocks[j].t = INT_MIN; 
      c.sets[i].blocks[j].LRU = 0; 
     } 

     i++; 
    } 

    FILE *f = fopen(file, "r"); 
    while(fscanf(f," %c %x,%d", &operation, &address, &size) != EOF) 
    { 
     check = 0; 
     curTag = ((unsigned int) address) >> (s+b); 
     curSet = (address >> b) & ((1 << s) - 1); 
     for (int i = 0; i < E; i++) 
     { 
      c.sets[curSet].blocks[i].LRU++; 
      if(c.sets[curSet].blocks[i].LRU >= maxLRU) 
      { 
       maxLRU = c.sets[curSet].blocks[i].LRU; 
       curLRU = i; 
      } 
      if(curTag == c.sets[curSet].blocks[i].t) 
      { 
       *hC = *hC + 1; 
       if (operation == 'M') 
       { 
        *hC = *hC + 1; 
       } 
       c.sets[curSet].blocks[i].LRU = 0; 
       check = 1; 
      } 
     } 
     if(check == 0) 
     { 
      for(int i = 0; i < E; i++) 
      { 
       if(c.sets[curSet].blocks[i].v == 0) 
       { 
        *mC = *mC + 1; 
        if (operation == 'M') 
        { 
         *hC = *hC + 1; 
        } 
        c.sets[curSet].blocks[i].v = 1; 
        c.sets[curSet].blocks[i].LRU = 0; 
        c.sets[curSet].blocks[i].t = curTag; 
        check = 1; 
        break; 
       } 
      } 
     } 
     if(check == 0) 
     { 
      *eC = *eC + 1; 
      *mC = *mC + 1; 
      if (operation == 'M') 
      { 
       *hC = *hC + 1; 
      } 
      c.sets[curSet].blocks[curLRU].t = curTag; 
      c.sets[curSet].blocks[curLRU].v = 1; 
      c.sets[curSet].blocks[curLRU].LRU = 0; 
     } 
    } 
    } 

    int main(int argc, char** argv) 
    { 
    int hitCount, missCount, evictionCount; 

    int s, E, b; 
    char *file; 
    char opt; 
    while((opt = getopt(argc,argv,"v:h:s:E:b:t:")) != -1) 
    { 
     switch(opt){ 
      case 'v': 
       break; 
      case 'h': 
       break; 
      case 's': 
       s = atoi(optarg); 
       break; 
      case 'E': 
       E = atoi(optarg); 
       break; 
      case 'b': 
       b = atoi(optarg); 
       break; 
      case 't': 
       file = optarg; 
       break; 
      default: 
       exit(1); 
     } 
    } 
    simulate(s, E, b, file, &hitCount, &missCount, &evictionCount); 

    printSummary(hitCount, missCount, evictionCount); 
    return 0; 
} 

EDIT:

Ich verstehe, dass dies zu einer Differenz zwischen Klirren und gcc zurückzuführen ist. Hat jemand Informationen darüber, wie ich diese Diskrepanz beheben kann?

Hier ist cachelab.c:

/* 
* cachelab.c - Cache Lab helper functions 
*/ 
#include <stdio.h> 
#include <stdlib.h> 
#include <assert.h> 
#include "cachelab.h" 
#include <time.h> 

trans_func_t func_list[MAX_TRANS_FUNCS]; 
int func_counter = 0; 

/* 
* printSummary - Summarize the cache simulation statistics. Student cache simulators 
*    must call this function in order to be properly autograded. 
*/ 
void printSummary(int hits, int misses, int evictions) 
{ 
    printf("hits:%d misses:%d evictions:%d\n", hits, misses, evictions); 
    FILE* output_fp = fopen(".csim_results", "w"); 
    assert(output_fp); 
    fprintf(output_fp, "%d %d %d\n", hits, misses, evictions); 
    fclose(output_fp); 
} 

/* 
* initMatrix - Initialize the given matrix 
*/ 
void initMatrix(int M, int N, int A[N][M], int B[M][N]) 
{ 
    int i, j; 
    srand(time(NULL)); 
    for (i = 0; i < N; i++){ 
     for (j = 0; j < M; j++){ 
      // A[i][j] = i+j; /* The matrix created this way is symmetric */ 
      A[i][j]=rand(); 
      B[j][i]=rand(); 
     } 
    } 
} 

void randMatrix(int M, int N, int A[N][M]) { 
    int i, j; 
    srand(time(NULL)); 
    for (i = 0; i < N; i++){ 
     for (j = 0; j < M; j++){ 
      // A[i][j] = i+j; /* The matrix created this way is symmetric */ 
      A[i][j]=rand(); 
     } 
    } 
} 

/* 
* correctTrans - baseline transpose function used to evaluate correctness 
*/ 
void correctTrans(int M, int N, int A[N][M], int B[M][N]) 
{ 
    int i, j, tmp; 
    for (i = 0; i < N; i++){ 
     for (j = 0; j < M; j++){ 
      tmp = A[i][j]; 
      B[j][i] = tmp; 
     } 
    } 
} 



/* 
* registerTransFunction - Add the given trans function into your list 
*  of functions to be tested 
*/ 
void registerTransFunction(void (*trans)(int M, int N, int[N][M], int[M][N]), 
          char* desc) 
{ 
    func_list[func_counter].func_ptr = trans; 
    func_list[func_counter].description = desc; 
    func_list[func_counter].correct = 0; 
    func_list[func_counter].num_hits = 0; 
    func_list[func_counter].num_misses = 0; 
    func_list[func_counter].num_evictions =0; 
    func_counter++; 
} 
+0

wo 'printSummary' definiert ist? –

+0

Wie wäre es mit cachelab.h? – cleblanc

+0

bearbeiten: enthalten cachelab.c, die printSummary enthält –

Antwort

6

Sie haben vergessen, die Zähler und Flags zu initialisieren, so dass sie bei undefinierten Werten starten. Die folgenden Zeilen:

int hitCount, missCount, evictionCount; 
int s, E, b; 

sollten sein:

int hitCount = 0, missCount = 0, evictionCount = 0; 
int s = 0, E = 0, b = 0; 

Es passiert einfach, dass die Anfangswerte passieren auf dem Mac zu niedriger sein so dass Sie nicht korrekten Ergebnisse auf dem Mac entweder (zumindest bekommen nicht garantiert, da der Anfangswert nicht definiert ist).

+0

@rici danke. Ich habe diese zur Antwort hinzugefügt. – fernan

Verwandte Themen