如何在我的缓存模拟中纠正我的写函数和/或我的辅助函数?

问题描述 投票:0回答:0

我有一个实现 FIFO 方法的缓存模拟,这里是关于缓存本身的详细信息:

• The cache has two levels
• A cache block is 16 bytes.
• Each address is accessing 1 bytes of data.
• The L1 cache is a 64 Bytes, 2-way set associative cache.
• The L2 cache is a 256 Bytes, 4-way set associative cache.
• The cache is inclusive, which mean that data in L1 cache will also remain in the L2 cache. In other
word, the data in L1 is a subset of the data in L2 (This assumption simplify your design).
• The cache is using a first-in-first-out cache replacement policy. Note that this is simpler to
implement than the LRU policy

这是我的实现:

#include "cacheSim.h"
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

unsigned int helper_L1(u_int32_t address, int a, char *fff);
unsigned int helper_L2(u_int32_t address, int b, char *fff);

// In this question, we will assume DRAM will take a 4-byte values starting from 0 to 
void init_DRAM()
{
    unsigned int i=0;
    DRAM = malloc(sizeof(char) * DRAM_SIZE);
    for(i=0;i<DRAM_SIZE/4;i++)
    {
        *((unsigned int*)DRAM+i) = i;
    }
}

void printCache()
{
    int i,j,k;
    printf("===== L1 Cache Content =====\n");
    for(i=0;i<2;i++)
    {
        printf("Set %d :", i);
        for(j=0;j<2;j++)
        {
            printf(" {(TAG: 0x%x)", (unsigned int)(L1_cache[i][j].tag));
            for(k=0;k<16;k++)
                printf(" 0x%x,", (unsigned int)(L1_cache[i][j].data[k]));
            printf(" |");
        }
        printf("\n");
    }
    printf("===== L2 Cache Content =====\n");
    for(i=0;i<4;i++)
    {
        printf("Set %d :", i);
        for(j=0;j<4;j++)
        {
            printf(" {(TAG: 0x%x)", (unsigned int)(L2_cache[i][j].tag));
            for(k=0;k<16;k++)
                printf(" 0x%x,", (unsigned int)(L2_cache[i][j].data[k]));
            printf(" |");
        }
        printf("\n");
    }
}

u_int32_t read_fifo(u_int32_t address)
{
    u_int32_t setID = getL1SetID(address);
    u_int32_t tag = getL1Tag(address);
    for (int i = 0; i < 2; i++) {
        if (L1_cache[setID][i].tag == tag) {
            return L1_cache[setID][i].data[address & 0xF];
        }
    }
    if (L2lookup(address)) {
        u_int32_t l2SetID = getL2SetID(address);
        for (int i = 0; i < 4; i++) {
            if (L2_cache[l2SetID][i].tag == tag) {
                cacheBlock temp = L1_cache[setID][0];
                L1_cache[setID][0] = L2_cache[l2SetID][i];
                L2_cache[l2SetID][i] = temp;
                return L1_cache[setID][0].data[address & 0xF];
            }
        }
    }
    u_int32_t l2SetID = getL2SetID(address);
    u_int32_t l2Tag = getL2Tag(address);
    cacheBlock newBlock;
    newBlock.tag = l2Tag;
    memcpy(newBlock.data, DRAM + (address & 0xFFFFFFF0), 16);
    cacheBlock temp = L2_cache[l2SetID][0];
    L2_cache[l2SetID][0] = newBlock;
    newBlock = temp;
    temp = L1_cache[setID][0];
    L1_cache[setID][0] = L2_cache[l2SetID][0];
    L2_cache[l2SetID][0] = temp;

    return L1_cache[setID][0].data[address & 0xF];
}


unsigned int getL1SetID(u_int32_t address)
{
    unsigned int setID = (address >> 4) & 1;
    return setID;
}

unsigned int getL1Tag(u_int32_t address)
{
    unsigned int tag = address >> 5;
    return tag;
}

unsigned int getL2SetID(u_int32_t address)
{
    unsigned int setID = ((address >> 4) & 3);
    return setID;
}

unsigned int getL2Tag(u_int32_t address)
{
    unsigned int tag = address >> 6;
    return tag;
}

int L1lookup(u_int32_t address)
{
    unsigned int setID = getL1SetID(address);
    unsigned int tag = getL1Tag(address);

    for(int i=0; i<2; i++)
    {
        if(L1_cache[setID][i].tag == getL1Tag(address)){
            return 1;
        }
    }

    return 0;
}

int L2lookup(u_int32_t address)
{
    unsigned int setID = getL2SetID(address);
    unsigned int tag = getL2Tag(address);

    for(int i=0; i<4; i++)
    {
        if(L2_cache[setID][i].tag == getL2Tag(address))
            return 1;
    }

    return 0;
}
//Below are the three helper functions I've talked about
unsigned int helper_L1(u_int32_t address, int a, char *fff){    
        memcpy(L1_cache[getL1SetID(address)][a].data, fff,16);     
        L1_cache[getL1SetID(address)][a].tag = getL1Tag(address);     
        L1_cache[getL1SetID(address)][a].timeStamp = cycles; 
}  
unsigned int helper_L2(u_int32_t address, int b, char *fff){     
         memcpy(L2_cache[getL2SetID(address)][b].data, fff,16);     
         L2_cache[getL2SetID(address)][b].tag = getL2Tag(address);     
         L2_cache[getL2SetID(address)][b].timeStamp = cycles; 
}  
unsigned int helper_L1look(u_int32_t address, int a, int j){     
         memcpy(L1_cache[getL1SetID(address)][a].data, L2_cache[getL2SetID(address)][j].data, 16);         
         L1_cache[getL1SetID(address)][a].tag = getL1Tag(address);     
         L1_cache[getL1SetID(address)][a].timeStamp = cycles; 
}   
//end of the three helper functions
//below here is the write function 
void write(u_int32_t address, u_int32_t data) {
    int byt = 15;
    int a = 0;
    int i = 0;

    do {
        if (L1_cache[getL1SetID(address)][a].timeStamp > L1_cache[getL1SetID(address)][i].timeStamp) {
            a = i;
        }
        if ((getL1Tag(address) ^ L1_cache[getL1SetID(address)][i].tag) != 1) {
            L1_cache[getL1SetID(address)][i].data[address & byt] = data;
        }
        i++;
    } while (i < 2);

    int b = 0;
    int j = 0;

    do {
        if (L2_cache[getL2SetID(address)][j].timeStamp < L2_cache[getL2SetID(address)][b].timeStamp) {
            b = j;
        }
        if ((getL2Tag(address) ^ L2_cache[getL2SetID(address)][j].tag) != 1) {
            L2_cache[getL2SetID(address)][j].data[address & byt] = data;
            if ((L1lookup(address)) == false) {
                helper_L1look(address, a, j);
            }
        }
        j++;
    } while (j < 4);

    int byte = 16;
    unsigned char fff[byte];
    int gf = address % byte;
    int r = 0;

    while (r < byte) {
        fff[r] = DRAM[gf++];
        r++;
    }

    fff[address & 15] = data;

    if (L1lookup(address) != true) {
        helper_L1(address, a, fff);
    }
    if (L2lookup(address) != true) {
        helper_L2(address, b, fff);
    }
    return;
}

问题是我在实现下面的 3 个

 unsigned int helper
函数时遇到了麻烦,最终是
void_write()
,因为我希望它们返回一个 unsigned int 但我不知道返回什么或如何返回,或者是否更改它作废与否。

如果您认为我应该更改功能,请告诉我如何更改。

重要

void_write()
应该假设为直写缓存,它对所有缓存级别执行写入(即,如果有对地址addr的写入,这个新值应该是 针对所有缓存级别以及 DRAM 进行了更新)。

这里是上面代码中使用的所有结构的结构:

#include<stdlib.h>
#include<stdio.h>
#define DRAM_SIZE 1048576

typedef struct cb_struct {
    unsigned char data[16]; // One cache block is 16 bytes.
    u_int32_t tag;
    u_int32_t timeStamp;   /// This is used to determine what to evict. You can update the timestamp using cycles.
}cacheBlock;


typedef struct access {
    int readWrite; // 0 for read, 1 for write
    u_int32_t address;
    u_int32_t data; // If this is a read access, value here is 0
}cacheAccess;

// This is our dummy DRAM. You can initialize this in anyway you want to test.
unsigned char * DRAM; 

cacheBlock L1_cache[2][2]; // Our 2-way, 64 byte cache
cacheBlock L2_cache[4][4]; // Our 4-way, 256 byte cache

// Trace points to a series of cache accesses.
FILE *trace;

long cycles;

void init_DRAM();


// This function print the content of the cache in the following format for an N-way cache with M Sets
// Set 0   : CB1 | CB2 | CB 3 | ... | CB N
// Set 1   : CB1 | CB2 | CB 3 | ... | CB N
// ...
// Set M-1 : CB1 | CB2 | CB 3 | ... | CB N
void printCache();
c caching simulation cpu-architecture
© www.soinside.com 2019 - 2024. All rights reserved.