2-way 8-sets 缓存的初始化
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
// 定义单个缓存线
typedef struct {
bool valid; // 有效位
bool dirty; // 脏位(可选)
uint32_t tag; // Tag 部分
uint8_t *data; // 实际数据(指向内存块)
} CacheLine;
// 定义缓存的 Set
typedef struct {
CacheLine lines[2]; // 每个 set 有 2 条缓存线(2-way)
} CacheSet;
// 定义缓存
typedef struct {
CacheSet sets[8]; // 缓存中有 8 个 sets
uint32_t line_size; // 每条缓存线大小
} Cache;
// 初始化缓存
void initializeCache(Cache *cache, uint32_t line_size) {
cache->line_size = line_size;
for (int i = 0; i < 8; i++) { // 8 个 sets
for (int j = 0; j < 2; j++) { // 每个 set 中有 2 条缓存线
cache->sets[i].lines[j].valid = false;
cache->sets[i].lines[j].dirty = false;
cache->sets[i].lines[j].tag = 0;
cache->sets[i].lines[j].data = (uint8_t *)malloc(line_size);
}
}
}
// 模拟访问地址
bool accessCache(Cache *cache, uint32_t address, uint8_t *memory) {
uint32_t line_size = cache->line_size;
uint32_t index = (address / line_size) % 8; // 从地址中提取 set index(3 bits)
uint32_t tag = address / (line_size * 8); // 提取 tag
// 遍历 set 中的每条缓存线(2-way)
for (int i = 0; i < 2; i++) {
CacheLine *line = &cache->sets[index].lines[i];
if (line->valid && line->tag == tag) { // 命中
printf("Address %u: Hit\n", address);
return true;
}
}
// 缺失,加载数据到缓存
printf("Address %u: Miss\n", address);
// 使用简单替换策略(如替换第一个空缓存线,或者随机替换)
CacheLine *lineToReplace = &cache->sets[index].lines[0];
if (cache->sets[index].lines[1].valid == false) {
lineToReplace = &cache->sets[index].lines[1];
}
// 如果需要 write-back,检查脏位
if (lineToReplace->dirty) {
uint32_t writeBackAddress = (lineToReplace->tag * 8 + index) * line_size;
memcpy(&memory[writeBackAddress], lineToReplace->data, line_size);
printf("Write-back to memory at address %u\n", writeBackAddress);
}
// 替换缓存线
lineToReplace->valid = true;
lineToReplace->dirty = false;
lineToReplace->tag = tag;
memcpy(lineToReplace->data, &memory[address], line_size);
return false;
}
// 清理缓存
void destroyCache(Cache *cache) {
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 2; j++) {
free(cache->sets[i].lines[j].data);
}
}
}