用C++编程实现主存-Cache地址映射(直接映射,组相联映射,全相联映射三种)(附运行成功截图+注释)
例:
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;
}
你可以根据需要修改mainMemorySize
、cacheSize
、blockSize
和associativity
等变量的值,以调整主存和缓存的大小以及组相联映射的组相联度。
下面是代码运行的示例截图,展示了直接映射、组相联映射和全相联映射的地址映射结果:
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
希望这能帮助到你实现主存-高速缓存地址映射!如有需要,请随时提问。
1.get()方法要经常获取对应值所以低层存储应该是hashMap;
2.要及时更新频次,每次使用过一个节点之后要更新频次,对于频次更新可以使用双向结构,每次插入首部,删除时直接删除尾部;常用的双向结构主要有双向队列,双向链表,队列可以满足put需求,但get方法使用完之后需要将该键值对更新至队首,队列对于该任务太过复杂。
3. 选用双向链表实现,链表节点中存储key,value以及链表前后节点的两个指针pre,next;
引用chatgpt4:
以下是三种主存-Cache地址映射的C++实现,包括直接映射、组相联映射和全相联映射。
#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;
}
```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
直接映射、全相联映射和组相联映射三种