directed-map cache简单示例

在这里插入图片描述
这张图的地址映射是基于直接映射缓存的策略进行的,以下是详细解释:


直接映射缓存的映射方式

  1. 缓存块号 (Cache Block Number):

    • 使用公式 Cache块号 = 主存块号 % 缓存块总数 来决定主存地址在哪个缓存块中存储。
    • 比如,这里 Cache块总数 = 4,所以 Cache块号 = 主存块号 % 4
  2. 主存块号 (Memory Block Number):

    • 主存地址通过 主存块号 = 地址 / 缓存行大小 转换为主存块号。
  3. 映射规则:

    • 主存地址经过计算后映射到特定的缓存块。

逐步分析表中地址映射过程

假设:

  • 缓存块总数 = 4
  • 主存地址直接映射到缓存块 (mod 4)
1. Address 0
  • 计算缓存块号0 % 4 = 0
  • 结果Address 0 被映射到缓存块 0。
  • 命中状态:缓存块 0 初始为空,发生 miss
  • 更新缓存:缓存块 0 被填入 Memory[0]

2. Address 8
  • 计算缓存块号8 % 4 = 0
  • 结果Address 8 也映射到缓存块 0。
  • 命中状态:缓存块 0 的内容为 Memory[0],标签不匹配,发生 miss
  • 更新缓存:缓存块 0 被替换为 Memory[8]

3. Address 0
  • 计算缓存块号0 % 4 = 0
  • 结果Address 0 映射到缓存块 0。
  • 命中状态:缓存块 0 的内容为 Memory[8],标签不匹配,发生 miss
  • 更新缓存:缓存块 0 被替换为 Memory[0]

4. Address 6
  • 计算缓存块号6 % 4 = 2
  • 结果Address 6 映射到缓存块 2。
  • 命中状态:缓存块 2 初始为空,发生 miss
  • 更新缓存:缓存块 2 被填入 Memory[6]

5. Address 8
  • 计算缓存块号8 % 4 = 0
  • 结果Address 8 映射到缓存块 0。
  • 命中状态:缓存块 0 的内容为 Memory[0],标签不匹配,发生 miss
  • 更新缓存:缓存块 0 被替换为 Memory[8]

总结

  • 缓存块号的计算方式主存块号 % 缓存块总数
  • 冲突缺失
    • Address 0Address 8 多次映射到同一个缓存块(块 0),导致频繁替换。
  • 命中和缺失统计
    • 共发生 5 次缺失 (miss),每次缺失都需要从主存加载数据。

映射规则的局限性

直接映射缓存由于其固定的映射规则,容易发生冲突缺失。在多次访问不同地址但映射到相同缓存块的情况下,会导致频繁替换,从而降低性能。

为什么mod 4

对地址进行 mod 4 的操作是为了确定地址应该映射到哪一个缓存块。使用二进制可以更直观地理解这个过程。以下是详细的二进制解释:


背景

  • 缓存块数:4(对应二进制为 00, 01, 10, 11 共 2 位)。
  • mod 4 的含义:将地址的低两位用作缓存块号,因为 2^2 = 4,低两位足以区分 4 个缓存块。

二进制视角

假设地址是 32 位的虚拟地址或物理地址(简化为 8 位进行说明),地址可以分为以下几个部分:

| 高位部分(Tag) | 缓存块号部分(Index) | 缓存行内偏移量(Offset) |
  • 高位部分(Tag):表示标签,用于判断是否是同一个主存块。
  • 缓存块号(Index):低两位(因为是 4 个块,对应 2^2)。
  • 偏移量(Offset):更低的位,用于访问缓存行内的具体字节(假设缓存行大小为 4 字节,则需要 2 位偏移量)。

示例

缓存结构假设
  • 缓存块数:4(需要 2 位 Index)。
  • 缓存行大小:4 字节(需要 2 位 Offset)。
  • 总地址大小:8 位(用于演示)。
地址 (二进制)标签 (Tag)IndexOffset
0000 0000 (0)00000000
0000 1000 (8)00000000
0000 0110 (6)00001000
映射过程
  • 地址的 Index 部分 决定了缓存块号。
  • 对于地址 0 (0000 0000),Index00,映射到缓存块 0。
  • 对于地址 8 (0000 1000),Index00,同样映射到缓存块 0。
  • 对于地址 6 (0000 0110),Index10,映射到缓存块 2。

这就解释了为什么地址 0 和 8 会冲突,因为它们的 Index 都是 00,但它们的 Tag 不同(区分主存块的标签)。


为什么使用 mod 4

  • 本质上是取低位索引值
    • mod 4 操作相当于取地址的低两位(二进制位数由缓存块数决定:log2(4) = 2)。
    • mod 8 会取低 3 位(如果缓存块数是 8)。
    • 这是通过位运算快速确定地址对应缓存块号的方式。
低位如何影响映射

假设我们有如下地址:

  • 地址 0 (0000 0000)00 (mod 4 = 0)
  • 地址 8 (0000 1000)00 (mod 4 = 0)
  • 地址 6 (0000 0110)10 (mod 4 = 2)

低位的 Index 决定了映射的块号(而不是高位 Tag)。


总结

  • mod 4 就是用地址的低 2 位(二进制)来确定缓存块号。
  • 使用二进制可以清楚地看到 Index 的作用,即如何根据低位分配缓存块。
  • 二进制的这种取位操作(Index 部分)通过硬件实现起来非常高效,避免了复杂的数学运算。

代码实现

要实现以上过程,我们可以使用一个简单的直接映射缓存模拟器。此缓存模拟器将使用主存地址的某些位来确定缓存块号,并存储数据到缓存中。以下是如何用C语言代码实现这个缓存访问模拟过程。

实现思路

  1. 定义缓存块:每个缓存块包含一个有效位、数据和标签。
  2. 计算缓存块号:通过(地址 % 4)来确定地址在哪个缓存块。
  3. 检查命中或缺失:检查对应块中标签是否匹配,并判断有效位,如果匹配则是命中,否则是缺失。
  4. 更新缓存块:在缺失的情况下,将数据加载到缓存块并更新标签和有效位。

代码说明

  • 结构定义CacheBlock结构体包含有效位valid、标签tag和数据data
  • initializeCache:初始化缓存,将所有有效位设置为false,标签设为-1
  • accessCache:模拟访问缓存:
    • 计算块号:address % CACHE_SIZE
    • 计算标签:address / CACHE_SIZE
    • 检查缓存块是否有效并且标签是否匹配,若匹配则命中,否则缺失并更新缓存块。
  • main:模拟一组地址的访问并统计缺失次数。

输出示例

根据示例地址序列的执行结果,输出可能如下:

Address 0: Miss
Address 8: Miss
Address 0: Miss
Address 6: Miss
Address 8: Miss
Total misses: 5

解释

此代码模拟了一个直接映射缓存,其中每次检查地址的有效性和标签是否匹配,若不匹配则视为缓存缺失并更新缓存块的内容。
为了使用一个内存数组memory[]来模拟内存数据存储,我们可以修改代码,将访问的地址值映射到memory[]中,从而在每次缓存缺失时从memory[]中加载数据到缓存。

修改后的代码示例

我们假设memory[]是一个较大的数组,用于模拟主存储器的内容。每次访问缓存时,如果发生缓存缺失,就从memory[]中加载数据到缓存。

#include <stdio.h>
#include <stdbool.h>#define CACHE_SIZE 4      // 缓存块的数量
#define MEMORY_SIZE 16    // 模拟内存大小(可以调整)// 定义缓存块结构
typedef struct {bool valid;    // 有效位int tag;       // 标签int data;      // 存储的数据
} CacheBlock;// 初始化缓存
void initializeCache(CacheBlock cache[]) {for (int i = 0; i < CACHE_SIZE; i++) {cache[i].valid = false;cache[i].tag = -1;cache[i].data = 0;}
}// 初始化内存
void initializeMemory(int memory[]) {for (int i = 0; i < MEMORY_SIZE; i++) {memory[i] = i * 10;  // 示例数据,可以是任意值}
}// 检查缓存是否命中,若缺失则从 memory[] 加载数据
bool accessCache(CacheBlock cache[], int memory[], int address) {int blockNumber = address % CACHE_SIZE;  // 计算缓存块号int tag = address / CACHE_SIZE;          // 计算标签if (cache[blockNumber].valid && cache[blockNumber].tag == tag) {printf("Address %d: Hit (Data: %d)\n", address, cache[blockNumber].data);return true; // 命中} else {printf("Address %d: Miss, loading from memory...\n", address);// 缺失,从 memory 加载数据到缓存块cache[blockNumber].valid = true;cache[blockNumber].tag = tag;cache[blockNumber].data = memory[address];return false; // 缺失}
}int main() {CacheBlock cache[CACHE_SIZE];int memory[MEMORY_SIZE];initializeCache(cache);initializeMemory(memory);// 模拟一组地址访问int addresses[] = {0, 8, 0, 6, 8};int misses = 0;for (int i = 0; i < 5; i++) {if (!accessCache(cache, memory, addresses[i])) {misses++;}}printf("Total misses: %d\n", misses);return 0;
}

代码说明

  • initializeMemory: 将memory[]数组初始化为示例数据,例如memory[i] = i * 10
  • accessCache: 模拟缓存访问:
    • 使用address % CACHE_SIZE计算缓存块号。
    • 使用address / CACHE_SIZE计算标签。
    • 如果缓存块有效且标签匹配,则为命中,否则为缺失。
    • 如果缺失,从memory[address]加载数据到缓存块。

解释

此代码模拟了一个直接映射缓存。每次访问地址时,检查缓存块是否有效且标签是否匹配,若不匹配则从memory[]中加载数据到缓存。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/18387.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot配置相关的内容

依赖Starter和Parent 查依赖坐标网站&#xff1a;Maven Repository: Search/Browse/Explorehttps://mvnrepository.com/ 设置配置文件 配置文件相关的配置 yml多个数据的书写 配置文件的读取

基于Python的仓库管理系统设计与实现

背景&#xff1a; 基于Python的仓库管理系统功能介绍 本仓库管理系统采用Python语言开发&#xff0c;利用Django框架和MySQL数据库&#xff0c;实现了高效、便捷的仓库管理功能。 用户管理&#xff1a; 支持员工和管理员角色的管理。 用户注册、登录和权限分配功能&#x…

使用tauri + naiveAdmin 构建桌面应用程序

非常好的如何部署naiveAdmin的文档笔记: 非常详细的 https://sx-code.github.io/wiki/adminpro/02_project_prepare/04_%E9%A1%B9%E7%9B%AE%E8%AE%BE%E7%BD%AE.html 阅读原码ing 前端框架 NaiveUiAdmin Rust 数据处理 ing … Mysql 数据库使用 ing …

RGB与YCbCr转换算法

目录 RGB与YCbCr转换算法RGB与YCbCr色域介绍RGB模型YCbCr色域简介YCbCr的应用YUV 和 YCbCr 的区别 色彩转换公式 RGB 转 YCbCr 实现RGB 转 YCbCr 的 Matlab 实现RGB 转 YCbCr 的 FPGA 实现 YCbCr 转 RGB 实现YCbCr 转 RGB 的 Matlab 实现YCbCr 转 RGB 的 FPGA 实现 RGB与YCbCr转…

【STM32】I2C通信协议

文章目录 I2C通信协议简介I2C协议硬件规定I2C协议软件规定I2C时序基本单元I2C典型时序 参考 STM32硬件I2C与软件模拟I2C超详解 I2C通信协议简介 I2C 也叫 IC、IIC (Inter-Integrated Circuit) &#xff0c;集成电路总线是由 Phiilps 公司开发的两线式串行总线&#xff0c;用于…

大数据挖掘

大数据挖掘 数据挖掘 数据挖掘定义 技术层面&#xff1a; 数据挖掘就是从大量的、不完全的、有噪声的、模糊的、随机的实际应用数据中&#xff0c;提取隐含在其中、人们事先不知道的、但又潜在有用的信息的过程。 数据准备环节 数据选择 质量分析 数据预处理 数据仓库 …

leetcode101:对称二叉树

给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;false提示&#xff1a; 树中节点数目在范围…

湘潭大学软件工程算法设计与分析考试复习笔记(一)

文章目录 前言随机类&#xff08;第七章&#xff09;随机概述数值随机化舍伍德拉斯维加斯蒙特卡罗 模拟退火遗传人工神经网络 回溯&#xff08;第五章&#xff09;动态规划&#xff08;第四章&#xff09;后记 前言 考试还剩十一天&#xff0c;现在准备开始复习这门课了。好像全…

Win11专业版Docker安装、配置记录

零&#xff0c;系统环境配置 首先&#xff0c;安装Docker需要系统支持开启硬件虚拟化及Hyper-V功能&#xff0c;所以这里需要Win10/11的专业版&#xff0c;这样才能进行Docker for Windows软件安装。 1&#xff0c;硬件虚拟化 至于如何开启硬件虚拟化&#xff0c;自行百度即…

【Android】线程池的初见

引言 在Android当中根据用途分为主线程与子线程&#xff0c;主线程当中主要处理与界面相关的操作&#xff0c;子线程主要进行耗时操作。除了Thread本身以外&#xff0c;在Android当中还有很多扮演者线程的角色&#xff0c;比如AsyncTask&#xff08; 底层为线程池&#xff0c;…

春秋云镜-2022网鼎杯

flag1 进入网站&#xff0c;发现是wordpress&#xff0c;这种一般都不会有啥直接漏洞&#xff0c;应该是插件漏洞&#xff0c;或者弱口令 fscan扫描ip 好像没扫出啥东西 wp-login进入后台 爆破密码&#xff0c;弱口令admin&#xff0c;123456&#xff0c;之前lazysysadmin好…

js ResizeObserver API

一、ResizeObserver 是什么 ResizeObserver 是一个浏览器提供的 JavaScript API&#xff0c;用于监测一个元素的大小变化。它可以帮助开发者在元素的宽度或高度发生改变时执行某些操作&#xff0c;比如调整布局、重新渲染内容等。 二、Resize Observer和监听resize的区别及其…

《探索Zynq MPSoC》学习笔记(三)

引言&#xff1a;本文简要介绍FPGA器件技术发展以及当今FPGA器件的体系架构和特性。 第二章 FPGA、Zynq和Zynq MPSoC&#xff08;2&#xff09; 在本章涵盖的三种器件类型中&#xff0c;FPGA是建立时间最长的&#xff0c;也是Zynq和Zynq MPSoC器件PL元件的基础。因此&#xf…

支持用户注册和登录、发布动态、点赞、评论、私信等功能的社交媒体平台创建!!!

需要整体源代码的可以在我的代码仓下载https://gitcode.com/speaking_me/social-media-platformTest.git 社交媒体平台 描述&#xff1a;社交媒体平台需要支持用户注册、发布动态、点赞、评论、私信等功能。 技术栈&#xff1a; 前端&#xff1a;React, Angular, Vue.js后端…

跨平台WPF框架Avalonia教程 十五

ListBox 列表框 列表框从元素源集合中显示多行元素&#xff0c;并允许选择单个或多个。 列表中的元素可以组合、绑定和模板化。 列表的高度会扩展以适应所有元素&#xff0c;除非特别设置&#xff08;使用高度属性&#xff09;&#xff0c;或由容器控件设置&#xff0c;例如…

STL之mapset续|红黑树篇

STL之map&set续|红黑树篇 红黑树红黑树的规则红黑树的模拟实现 map&set的模拟实现封装map/set关于红黑树的复用红黑树模板参数set的const迭代器问题 红黑树 红黑树也是一种搜索二叉树&#xff0c;它通过颜色和规则控制树上没有一条路径会比其他路径长两倍&#xff0c;…

三、计算机视觉_03LeNet5及手势识别案例

1 LeNet-5基本介绍 LeNet-5是一种经典的卷积神经网络&#xff08;CNN&#xff09;架构&#xff0c;由Yann LeCun在1998年提出&#xff0c;用于手写数字识别&#xff0c;LeNet-5是卷积神经网络的开创性工作之一&#xff0c;它引入了卷积层、池化层和全连接层的组合&#xff0c;为…

【论文模型复现】深度学习、地质流体识别、交叉学科融合?什么情况,让我们来看看

文献&#xff1a;蓝茜茜,张逸伦,康志宏.基于深度学习的复杂储层流体性质测井识别——以车排子油田某井区为例[J].科学技术与工程,2020,20(29):11923-11930. 本文目录 一、前言二、文献阅读-基于深度学习的复杂储层流体性质测井识别2.1 摘要2.2 当前研究不足2.3 本文创新2.4 论文…

Uni-APP+Vue3+鸿蒙 开发菜鸟流程

参考文档 文档中心 运行和发行 | uni-app官网 AppGallery Connect DCloud开发者中心 环境要求 Vue3jdk 17 Java Downloads | Oracle 中国 【鸿蒙开发工具内置jdk17&#xff0c;本地不使用17会报jdk版本不一致问题】 开发工具 HBuilderDevEco Studio【目前只下载这一个就…

Unity-Editor扩展Odin + 自定义EditorWindow记录

没有上下文&#xff0c;可能你不知道这是什么&#xff08;关于Odin Inspector) 在写一个 Odin 插件的完整文章&#xff0c;卡了三天&#xff0c;之后会放出 使用Unity的人之中 1/10 可能会使用Editor扩展&#xff0c;而这之中的又1/10的 人可能会用Odin这个Editor的附加扩展 -…