C语言 C 中的缓存模拟器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2756068/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:20:55  来源:igfitidea点击:

Cache Simulator in C

c

提问by DuffDuff

Ok this is only my second question, and it's quite a doozy. It's for a school assignment, but no one (including the TAs) seems to be able to help me. It's kind of a tall order but I'm not sure where else to turn.

好的,这只是我的第二个问题,这很糟糕。这是一项学校作业,但似乎没有人(包括助教)能够帮助我。这是一项艰巨的任务,但我不知道还能去哪里。

Essentially the assignment was to make a cache simulator. This version is direct mapping and is actually only a small portion of the whole project, but if I can't even get this down I have no chance with other associativities. I'm posting my whole code because I don't want to make any assumptions about where the problem is.

本质上,任务是制作一个缓存模拟器。这个版本是直接映射,实际上只是整个项目的一小部分,但如果我什至无法解决这个问题,我就没有机会与其他关联。我发布我的整个代码是因为我不想对问题出在哪里做出任何假设。

This is the test case: http://www.mediafire.com/?ty5dnihydnw

这是测试用例:http: //www.mediafire.com/?ty5dnihydnw

And you run the following command:
./sims 512 direct 32 fifo wt pinatrace.out

然后运行以下命令:
./sims 512 direct 32 fifo wt pinatrace.out

You're supposed to get:

你应该得到:

hits: 604037
misses 138349
writes: 239269
reads: 138349

But I get:

但我得到:

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

If anyone could at least point me in the right direction it would be greatly appreciated. I've been stuck on this for about 12 hours.

如果有人至少能指出我正确的方向,我将不胜感激。我已经坚持了大约 12 个小时。

#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] = '
    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);
    }
'; } 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] = '##代码##'; // 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]='##代码##'; for (xindex=0, kindex=(32-(blockbits+setbits)); kindex<32-(blockbits); kindex++, xindex++){ sbits[xindex] = output[kindex]; } sbits[xindex]='##代码##'; for (xindex=0, lindex=0; lindex<(32-(blockbits+setbits)); lindex++, xindex++){ tbits[xindex] = output[lindex]; } tbits[xindex]='##代码##'; //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); }

采纳答案by caf

You've got two problems. Firstly, Scott Wales is correct about your hex2bin()function - you have a 'x'where you mean '4'.

你有两个问题。首先,斯科特威尔士对你的hex2bin()功能是正确的- 你有一个'x'你的意思'4'

Secondly, you are not correctly counting a cache miss when you hit an invalid cache slot. You can simply handle "invalid" with exactlythe same code path you use for a miss:

其次,当您遇到无效的缓存槽时,您没有正确计算缓存未命中。您可以使用与用于未命中的完全相同的代码路径来简单地处理“无效” :

##代码##