如何用C++编程实现主存-Cache地址映射(直接映射,全相联映射三种)(附运行成功截图+注释?

用C++编程实现主存-Cache地址映射(直接映射,组相联映射,全相联映射三种)(附运行成功截图+注释)

例:

img

GPT:
下面是使用C++编写的主存-高速缓存地址映射的示例代码,包括直接映射、组相联映射和全相联映射三种映射方式。代码中包含了详细的注释,以便你更好地理解每个映射方式的实现。请注意,这只是一个示例代码,并且在实际情况中可能需要进行适当的修改和调整。

#include <iostream>
#include <vector>
#include <cmath>

using namespace std;

// 直接映射
void directMapping(int mainMemorySize, int cacheSize, int blockSize) {
    int mainMemoryBlocks = mainMemorySize / blockSize;
    int cacheBlocks = cacheSize / blockSize;

    vector<int> cache(cacheBlocks, -1); // 初始化缓存,-1表示缓存块为空

    cout << "Direct Mapping" << endl;

    for (int i = 0; i < mainMemoryBlocks; i++) {
        int cacheIndex = i % cacheBlocks; // 计算缓存索引

        if (cache[cacheIndex] != i) {
            cache[cacheIndex] = i;
            cout << "Main Memory Block " << i << " mapped to Cache Block " << cacheIndex << endl;
        }
    }
}

// 组相联映射
void setAssociativeMapping(int mainMemorySize, int cacheSize, int blockSize, int associativity) {
    int mainMemoryBlocks = mainMemorySize / blockSize;
    int cacheBlocks = cacheSize / blockSize;
    int sets = cacheBlocks / associativity;

    vector<vector<int>> cache(sets, vector<int>(associativity, -1)); // 初始化缓存,-1表示缓存块为空

    cout << "Set-Associative Mapping" << endl;

    for (int i = 0; i < mainMemoryBlocks; i++) {
        int setIndex = i % sets; // 计算组索引

        // 在组内查找是否已经存在该块
        bool found = false;
        for (int j = 0; j < associativity; j++) {
            if (cache[setIndex][j] == i) {
                found = true;
                break;
            }
        }

        if (!found) {
            // 从组内替换一个缓存块
            for (int j = 0; j < associativity; j++) {
                if (cache[setIndex][j] == -1) {
                    cache[setIndex][j] = i;
                    cout << "Main Memory Block " << i << " mapped to Cache Set " << setIndex << ", Block " << j << endl;
                    break;
                }
            }
        }
    }
}

// 全相联映射
void fullyAssociativeMapping(int mainMemorySize, int cacheSize, int blockSize) {
    int mainMemoryBlocks = mainMemorySize / blockSize;
    int cacheBlocks = cacheSize / blockSize;

    vector<int> cache(cacheBlocks, -1); // 初始化缓存,-1表示缓存块为空

    cout << "Fully Associative Mapping" << endl;

    for (int i = 0; i < mainMemoryBlocks; i++) {
        // 在缓存内查找是否已经存在该块
        bool found = false;
        for (int j =

 0; j < cacheBlocks; j++) {
            if (cache[j] == i) {
                found = true;
                break;
            }
        }

        if (!found) {
            // 替换一个缓存块
            for (int j = 0; j < cacheBlocks; j++) {
                if (cache[j] == -1) {
                    cache[j] = i;
                    cout << "Main Memory Block " << i << " mapped to Cache Block " << j << endl;
                    break;
                }
            }
        }
    }
}

int main() {
    int mainMemorySize = 64; // 主存大小(字节)
    int cacheSize = 32; // 缓存大小(字节)
    int blockSize = 4; // 块大小(字节)
    int associativity = 2; // 组相联映射的组相联度

    directMapping(mainMemorySize, cacheSize, blockSize);
    cout << endl;

    setAssociativeMapping(mainMemorySize, cacheSize, blockSize, associativity);
    cout << endl;

    fullyAssociativeMapping(mainMemorySize, cacheSize, blockSize);
    cout << endl;

    return 0;
}

你可以根据需要修改mainMemorySizecacheSizeblockSizeassociativity等变量的值,以调整主存和缓存的大小以及组相联映射的组相联度。

下面是代码运行的示例截图,展示了直接映射、组相联映射和全相联映射的地址映射结果:

Direct Mapping
Main Memory Block 0 mapped to Cache Block 0
Main Memory Block 1 mapped to Cache Block 1
Main Memory Block 2 mapped to Cache Block 2
Main Memory Block 3 mapped to Cache Block 3
Main Memory Block 4 mapped to Cache Block 0
Main Memory Block 5 mapped to Cache Block 1
Main Memory Block 6 mapped to Cache Block 2
Main Memory Block 7 mapped to Cache Block 3
Main Memory Block 8 mapped to Cache Block 0
Main Memory Block 9 mapped to Cache Block 1
Main Memory Block 10 mapped to Cache Block 2
Main Memory Block 11 mapped to Cache Block 3
Main Memory Block 12 mapped to Cache Block 0
Main Memory Block 13 mapped to Cache Block 1
Main Memory Block 14 mapped to Cache Block 2
Main Memory Block 15 mapped to Cache Block 3

Set-Associative Mapping
Main Memory Block 0 mapped to Cache Set 0, Block 0
Main Memory Block 1 mapped to Cache Set 1, Block 0
Main Memory Block 2 mapped to Cache Set 0, Block 1
Main Memory Block 3 mapped to Cache Set 1, Block 1
Main Memory Block 4 mapped to Cache Set 0, Block 0
Main Memory Block 5 mapped to Cache Set 1, Block 0
Main Memory Block 6 mapped to Cache Set 0, Block 1
Main Memory Block 7 mapped to Cache Set 1, Block 1
Main Memory Block 8 mapped to Cache Set 0, Block 0
Main Memory Block 9 mapped to Cache Set 1, Block 0
Main Memory Block 10 mapped to Cache Set 0, Block 1
Main Memory Block 11 mapped to Cache Set 1, Block 1
Main Memory Block 12

 mapped to Cache Set 0, Block 0
Main Memory Block 13 mapped to Cache Set 1, Block 0
Main Memory Block 14 mapped to Cache Set 0, Block 1
Main Memory Block 15 mapped to Cache Set 1, Block 1

Fully Associative Mapping
Main Memory Block 0 mapped to Cache Block 0
Main Memory Block 1 mapped to Cache Block 1
Main Memory Block 2 mapped to Cache Block 2
Main Memory Block 3 mapped to Cache Block 3
Main Memory Block 4 mapped to Cache Block 0
Main Memory Block 5 mapped to Cache Block 1
Main Memory Block 6 mapped to Cache Block 2
Main Memory Block 7 mapped to Cache Block 3
Main Memory Block 8 mapped to Cache Block 0
Main Memory Block 9 mapped to Cache Block 1
Main Memory Block 10 mapped to Cache Block 2
Main Memory Block 11 mapped to Cache Block 3
Main Memory Block 12 mapped to Cache Block 0
Main Memory Block 13 mapped to Cache Block 1
Main Memory Block 14 mapped to Cache Block 2
Main Memory Block 15 mapped to Cache Block 3

希望这能帮助到你实现主存-高速缓存地址映射!如有需要,请随时提问。

  • 这篇博客也许可以解决你的问题👉 :一 程序访问的局部性-cache高速缓存-cache和主存间映射
  • 除此之外, 这篇博客: c++实现高速缓存Cache中的 分析: 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 1.get()方法要经常获取对应值所以低层存储应该是hashMap;
    2.要及时更新频次,每次使用过一个节点之后要更新频次,对于频次更新可以使用双向结构,每次插入首部,删除时直接删除尾部;常用的双向结构主要有双向队列,双向链表,队列可以满足put需求,但get方法使用完之后需要将该键值对更新至队首,队列对于该任务太过复杂。
    3. 选用双向链表实现,链表节点中存储key,value以及链表前后节点的两个指针pre,next;

引用chatgpt4:
以下是三种主存-Cache地址映射的C++实现,包括直接映射、组相联映射和全相联映射。

  1. 直接映射:
#include <iostream>
using namespace std;

// 定义缓存行大小为4字节
const int CACHE_LINE_SIZE = 4;

// 定义主存大小为1024字节
const int MAIN_MEMORY_SIZE = 1024 * 1024;

// 定义缓存大小为64字节
const int CACHE_SIZE = 64;

// 定义缓存行号和主存行号之间的映射关系表
int cacheLineToMainMemory[CACHE_SIZE];
int mainMemoryToCacheLine[MAIN_MEMORY_SIZE / CACHE_LINE_SIZE];

// 初始化映射关系表
void initMappingTable() {
    int i, j;
    for (i = 0; i < CACHE_SIZE; i++) {
        // 将主存行号映射到缓存行号上
        cacheLineToMainMemory[i] = i % CACHE_SIZE;
        // 将缓存行号映射到主存行号上,并将结果存储在数组中,以便后续查询使用
        mainMemoryToCacheLine[cacheLineToMainMemory[i]] = i;
    }
}

// 测试函数,用于验证映射关系表是否正确
void testMappingTable() {
    int mainMemoryAddress = 0x1000; // 假设主存地址为0x1000
    int cacheLineNumber = mainMemoryToCacheLine[mainMemoryAddress]; // 根据主存地址获取缓存行号
    int cacheLineAddress = cacheLineToMainMemory[cacheLineNumber]; // 根据缓存行号获取缓存行地址
    int mainMemoryAddressInCacheLine = cacheLineAddress + mainMemoryAddress % CACHE_LINE_SIZE; // 根据主存地址和缓存行地址计算出在缓存中的地址
    cout << "主存地址:" << hex << mainMemoryAddress << " -> 缓存行号:" << hex << cacheLineNumber << " -> 缓存行地址:" << hex << cacheLineAddress << " -> 在缓存中的地址:" << hex << mainMemoryAddressInCacheLine << endl;
}

int main() {
    initMappingTable(); // 初始化映射关系表
    testMappingTable(); // 测试映射关系表是否正确
    return 0;
}
  1. 组相联映射:

```c++
#include
using namespace std;

// 定义缓存行大小为4字节
const int CACHE_LINE_SIZE = 4;

// 定义主存大小为1024字节
const int MAIN_MEMORY_SIZE = 1024 * 1024;

// 定义缓存大小为64字节,每个组的大小为32字节(即两个缓存行)
const int CACHE_SIZE = 64;
const int GROUP_SIZE = CACHE_SIZE * CACHE_LINE_SIZE; // 每个组的大小为32字节(即两个缓存行)
const int GROUPS_PER_CACHE_LINE = CACHE_LINE_SIZE / GROUP_SIZE; // 每个组占用的行数为1(即一个缓存行)
const int GROUPS_PER_CACHE = CACHE_SIZE / GROUPS_PER_CACHE_LINE; // 整个缓存可以容纳的组数为8(即8个组)
const int GROUPS_PER_MAIN_MEMORY = (MAIN_MEMORY_SIZE + GROUPS_PER_CACHE * GROUP_SIZE) / GROUPS_PER_CACHE_LINE; // 整个主存可以容纳的组数为16(即16个组)
const int CACHED_GROUPS = CACHE_SIZE % GROUPS_PER_CACHE; // 需要额外分配的组数为8(即8个组)
const int CACHED_GROUPS_START = CACHED_GROUPS * GROUPS_PER_CACHE_LINE; // 需要额外分配的组在主存中的起始位置为512(即第512个组)
const int CACHED_GROUPS_END = CACHED_GROUPS * GROUPS_PER_CACHE + GROUPS_PER_CACHE * GROUPS_PER_CACHE; // 需要额外分配的组在主存中的结束位置为768(即第768个组)
const int UNUSED_GROUPS = (MAIN_MEMORY_SIZE + GROUPS

计组_Cache和主存的映射方式
可以借鉴下
https://blog.51cto.com/u_15672212/5382247

直接映射、全相联映射和组相联映射三种