简体   繁体   English

lang和海湾合作委员会之间的行为差​​异?

[英]Difference in behavior between clang and gcc?

I'm writing a C function to simulate a cache given an address trace. 我正在编写一个C函数来模拟给定地址跟踪的缓存。 The function works as expected when compiled on my mac using gcc (really clang). 使用gcc(确实是clang)在我的Mac上编译时,该功能按预期工作。 gcc --version on my mac returns this: 我的Mac上的gcc --version返回以下内容:

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)

When I compile the same program on linux using gcc, the returns are way off, and eC & hC in my program (cache eviction counter and hit counter) are in the hundreds of thousands, when they should be below 10. When typing gcc --version on the linux machine, it returns this: 当我使用gcc在linux上编译同一程序时,返回值很低,并且程序中的eC和hC(高速缓存逐出计数器和命中计数器)成千上万,应该低于10。输入gcc- -version在linux机器上,它返回以下内容:

gcc (Ubuntu 4.9.3-8ubuntu2~14.04) 4.9.3 gcc(Ubuntu 4.9.3-8ubuntu2〜14.04)4.9.3

Here is the program: 这是程序:

    #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: 编辑:

I understand that this is due to a difference between clang and gcc. 我知道这是由于clang和gcc之间的差异。 Does anyone have any information about how I can go about fixing this discrepancy? 有人知道我如何解决此差异吗?

Here is cachelab.c: 这是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++;
}

You forgot to initialize the counters and flags so they start at undefined values. 您忘记了初始化计数器和标志,因此它们以未定义的值开始。 The following lines: 以下几行:

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

should be: 应该:

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

It just happens that the initial values happen to be lower on the mac so you're not getting correct results on the mac either (at least not guaranteed since the initial value is undefined). 碰巧Mac上的初始值恰好较低,因此您在Mac上也无法获得正确的结果(至少不能保证,因为初始值未定义)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM