cache(二)直接缓存映射

在知乎发现一份不错得学习资料 请教CPU的cache中关于line,block,index等的理解?
PPT 地址 https%3A//cs.slu.edu/%7Efritts/CSCI224_S15/schedule/chap6-cache-memory.pptx
课程主页 https://cs.slu.edu/~fritts/CSCI224_S15/schedule/

0. 缓存定义

在这里插入图片描述
这张图展示了缓存的通用组织结构,通过参数 ( S )、( E )、和 ( B ) 来定义缓存的配置。具体解释如下:

  1. 缓存的组成部分

    • Set(组):缓存被分为多个组,图中每一行表示一个组。
    • Line(行):每个组包含若干行。行代表缓存中存储数据块的单元。
    • Block(块):每行包含一个数据块,数据块由多个字节组成。
  2. 参数解释

    • ( S = 2^s )(组的数量):缓存中一共有 ( S ) 个组。
    • ( E = 2^e )(每组的行数):每个组包含 ( E ) 行,也可以称为组相联度。例如,( E = 1 ) 表示直接映射缓存,( E > 1 ) 表示组相联缓存。
    • ( B = 2^b )(每块的字节数):每个缓存块的数据量是 ( B ) 个字节。
  3. 缓存大小计算

    • 缓存的总大小 ( C ) 计算公式为:
      C = S × E × B C = S \times E \times B C=S×E×B
    • 这个公式表示缓存的容量等于组数乘以每组的行数再乘以每块的字节数。
  4. 每行的结构

    • 有效位(Valid Bit):用于指示这一行是否包含有效的数据。
    • 标记(Tag):标识主存中数据块的标记,用于在缓存中定位具体的地址。
    • 数据(Data):实际存储的数据块,每块包含 ( B ) 个字节。
  5. 工作机制

    • 当访问一个地址时,首先根据地址中的组编号定位到特定的组。
    • 然后根据标记位判断所需的数据块是否在该组中(即是否命中)。
    • 如果命中,则读取数据块中的内容;如果未命中,则需要将数据从主存加载到缓存中。

总结:图中的结构展示了缓存的典型组织方式,包括组、行和块。通过参数 ( S )、( E )、和 ( B ) 定义了缓存的结构和大小,具体到每行的结构,包括有效位、标记位和数据块。

1. 定义

在这里插入图片描述
这张图展示了**直接映射缓存(Direct Mapped Cache)**的一个例子,具体参数为 ( E = 1 ),即每个组(Set)只有一行(Line)。图中的假设是缓存块大小为 8 字节。

图中的关键要素

  1. 直接映射缓存的定义

    • 在直接映射缓存中,每个内存地址都唯一地映射到缓存的一个特定位置。
    • 这里的 ( E = 1 ) 表示每个组只有一行,因此每个地址只能映射到一个组内的唯一行。
  2. 缓存结构

    • 缓存被分成多个组(图中标示为 ( S = 2^s ) 个组),每个组包含一个行。
    • 每个行包含有效位(Valid Bit)、标记位(Tag)和一个数据块(大小为 8 字节,对应索引 0 到 7 的字节)。
  3. 地址分解

    • 地址被分解成三个部分:标记位(Tag)、组索引(Set Index)和块偏移量(Block Offset)。
      • 标记位(Tag):用于验证缓存中数据的唯一性,防止地址冲突。
      • 组索引(Set Index):用于定位特定的组。在图中,地址的组索引部分显示为二进制的 0...01,用以找到正确的组。
      • 块偏移量(Block Offset):在缓存行的数据块中定位到具体字节。图中示例的块偏移量为 100,表示需要读取数据块中的第 4 个字节(从 0 开始计数)。
  4. 地址查找流程

    • 定位组:根据地址的组索引 0...01,系统找到特定的组。
    • 检查标记:然后检查该组中的行是否有相应的标记位(Tag)与地址中的标记位匹配,并且有效位(Valid Bit)是否为1。
      • 如果匹配并且有效位为1,则表示缓存命中,可以直接读取数据。
      • 如果不匹配或者有效位为0,则发生缓存未命中,需要从主存加载数据。
    • 读取数据:在缓存命中的情况下,通过块偏移量 100 从数据块的第 4 个字节开始读取数据。

例子的说明

  • 缓存大小:因为每个组只有一行(直接映射),所以在直接映射缓存中,每个内存地址只会映射到唯一的缓存位置。这种方式简单高效,但可能会导致较高的冲突率(不同的地址可能映射到同一组,导致数据被频繁替换)。
  • 示例中的地址:假设的地址中,组索引和块偏移量共同确定了访问的组和字节位置。

总结

这个例子展示了直接映射缓存的读取过程。通过地址的组索引定位组,通过标记位验证缓存行的有效性,并利用块偏移量定位到具体数据的位置。直接映射缓存的优点是结构简单,但可能因为冲突而降低缓存效率。

2. set中第二行表示

在这里插入图片描述
这张图展示了直接映射缓存中发生**缓存未命中(Cache Miss)**时的数据替换过程。具体描述如下:

图中步骤和流程

  1. 初始状态

    • 上半部分显示了当前缓存行的状态。
    • 地址被分解为三个部分:标记位(Tag)、组索引(Set Index),以及块偏移量(Block Offset)。
    • 处理器要访问一个整数(int),地址中指定的组和块偏移量指向了缓存的一个位置。
    • 缓存行中的有效位(Valid Bit)显示该行是有效的,并且标记位用来判断数据是否匹配。
    • 在此情况下,假设此地址的标记不匹配当前缓存行的标记位,因此发生了缓存未命中(No match)。
  2. 缓存未命中的处理

    • 缓存未命中意味着当前请求的数据块不在缓存中,因此需要从主存(Memory)中加载该数据块。
    • 根据直接映射缓存的策略,未命中时,缓存会将当前行的数据逐出(Evict),并将新数据块加载进来。
    • 下半部分展示了替换后的缓存行,其中原有的数据被新数据块替换。
  3. 加载新数据块

    • 新数据块加载到缓存后,标记位更新为新数据块的标记,表示这行缓存现在存储的是新的数据块。
    • 有效位依然为1,表明这一行现在包含有效的数据。
    • 偏移量指向数据块中的具体字节位置,从该位置读取数据。
    • 在这个例子中,整数数据(int)被存储在数据块的第4到第7字节(图中标注为绿色)。
  4. 总结

    • 缓存未命中导致缓存中的数据被替换为新的数据块。
    • 替换后,处理器可以根据偏移量读取到所需的数据。
    • 直接映射缓存的特点是每个组只有一个行,因此一旦发生未命中,当前行的数据就会被新数据块替换,容易导致冲突。

图中标注的说明

  • No match:上半部分红色文字表示缓存未命中。
  • Old line is evicted and replaced:未命中后,原有的缓存行被逐出,并由新数据块替换。
  • Block offset:块偏移量用于确定数据块中的具体字节位置。

总结

这个图例展示了直接映射缓存中未命中的处理流程。在未命中时,旧数据被替换,新数据块被加载到缓存行中,并更新了标记位和数据。这样,处理器可以在缓存中读取到最新的数据块。

3. 例子

在这里插入图片描述
这张图展示了一个具有特定配置的直接映射缓存示例,详细描述了缓存初始化、地址访问轨迹(Address Trace)及缓存命中或未命中情况,并展示了最终的缓存配置。具体说明如下:

配置参数

  • M = 16 字节地址空间:主存大小为 16 字节。
  • B = 2 字节/块:每个缓存块包含 2 字节。
  • S = 4 个组(Sets):缓存有 4 个组。
  • E = 1 块/组:每个组只有 1 个块,即直接映射缓存。

地址分解

  • 地址被分为三部分:
    • t = 1:1 位的标记位(Tag)。
    • s = 2:2 位的组索引(Set Index)。
    • b = 1:1 位的块偏移量(Block Offset)。

初始缓存配置

  • 图中右上角显示了缓存的初始配置。
  • 初始状态下,仅组 0 包含有效数据,标记位为 1,且该块存储的是主存中地址 8 和 9 的数据,即 M[8-9]

地址访问轨迹(Address Trace)

按顺序访问一系列地址,并记录每次访问的结果(命中或未命中):

  1. 地址 0 ([0000]_2):未命中(Miss)。

    • 计算组索引为 0,标记为 0。
    • 因为当前组 0 的标记为 1,不匹配,因此未命中。
    • 加载主存地址 0 和 1 的数据块 M[0-1] 到组 0,并更新标记位为 0。
  2. 地址 1 ([0001]_2):命中(Hit)。

    • 同样映射到组 0,标记为 0,与缓存中的标记匹配。
    • 因此直接命中。
  3. 地址 7 ([0111]_2):未命中(Miss)。

    • 计算组索引为 3,标记为 0。
    • 组 3 为空,因此未命中。
    • 加载主存地址 6 和 7 的数据块 M[6-7] 到组 3,标记位更新为 0。
  4. 地址 8 ([1000]_2):未命中(Miss)。

    • 计算组索引为 0,标记为 1。
    • 组 0 中的标记为 0,不匹配,因此未命中。
    • 替换组 0 中的内容,加载主存地址 8 和 9 的数据块 M[8-9],并将标记位更新为 1。
  5. 地址 0 ([0000]_2):未命中(Miss)。

    • 组索引为 0,标记为 0。
    • 当前组 0 的标记为 1,不匹配,因此未命中。
    • 替换组 0 中的内容为 M[0-1],标记位更新为 0。
  6. 地址 A ([1010]_2):未命中(Miss)。

    • 组索引为 1,标记为 1。
    • 组 1 为空,因此未命中。
    • 加载主存地址 10 和 11 的数据块 M[10-11],标记位更新为 1。
  7. 地址 6 ([0110]_2):命中(Hit)。

    • 组索引为 3,标记为 0,与缓存中的标记匹配,因此命中。

最终缓存配置

图中右下角显示了最终的缓存状态:

  • Set 0:有效位 1,标记位 0,包含 M[0-1]
  • Set 1:有效位 1,标记位 1,包含 M[10-11]
  • Set 2:无数据(有效位 0)。
  • Set 3:有效位 1,标记位 0,包含 M[6-7]

总结

此示例展示了直接映射缓存的工作过程,包括地址分解、命中判断和替换。

3.1 最后一位作用

在这个缓存配置示例中,最后一位(即 块偏移量(block offset) 位)确实没有参与缓存行选择标记匹配过程。具体原因如下:

地址位分解

  • 这里的地址结构如下所示:
    • t = 1:1 位的标记(Tag),用于判断数据是否在缓存中。
    • s = 2:2 位的组索引(Set Index),用于选择缓存中的特定组。
    • b = 1:1 位的块偏移量(Block Offset),用于在缓存块内定位特定字节。

块偏移量的作用

  • 块偏移量用来定位缓存块内的具体字节,但不会参与组选择或标记匹配
  • 在本例中,每个块大小为 2 字节,因此块偏移量 b = 1 位,表示可以选择块中的两个字节之一。
    • 例如,地址 00000001 都会映射到相同的缓存组和标记,因为它们的前 3 位相同,最后一位(块偏移量)只是选择块内的具体字节。

为什么块偏移量不用于组选择

  • 组选择只取决于组索引位
  • 标记匹配只取决于标记位
  • 块偏移量的作用仅限于定位块内的具体字节,并不用于决定数据在缓存中的位置或是否命中。

总结

块偏移量(最后一位)在此示例中并未用于决定是否命中或替换,而仅用于确定缓存块中的具体字节位置。

4. 代码

在这里插入图片描述
这个图展示了在缓存中访问二维数组的两种不同方式对性能的影响。通过 sum_array_rowssum_array_cols 两种函数,展示了按行访问和按列访问的区别。

缓存的假设配置

  • 每个缓存组包含一个块(One block per set)。
  • 每个块可以存储 8 个 double 类型的数据(即 64 字节,因为一个 double 占用 8 字节)。
  • 初始状态为冷缓存(cold cache),即缓存是空的。

函数分析

  1. sum_array_rows 函数(按行访问)

    int sum_array_rows(double a[16][16]) {
        int i, j;
        double sum = 0;
        for (i = 0; i < 16; i++)
            for (j = 0; j < 16; j++)
                sum += a[i][j];
        return sum;
    }
    
    • 访问模式:按行访问,即 a[i][j],对于每个 ij 从 0 到 15 遍历。这意味着程序会连续访问数组的一行内的元素。
    • 缓存效果:由于每个块可以存储 8 个 double,当访问 a[i][0] 时,a[i][0]a[i][7] 会被加载到同一个缓存块中。
      • 当访问到 a[i][1]a[i][7] 时,数据已经在缓存中,命中率较高。
      • 然后访问 a[i][8] 时,会加载 a[i][8]a[i][15],这段访问也会命中。
    • 结果:按行访问时,缓存命中率较高,效率较高。
  2. sum_array_cols 函数(按列访问)

    int sum_array_cols(double a[16][16]) {
        int i, j;
        double sum = 0;
        for (j = 0; j < 16; j++)
            for (i = 0; i < 16; i++)
                sum += a[i][j];
        return sum;
    }
    
    • 访问模式:按列访问,即 a[i][j],对于每个 ji 从 0 到 15 遍历。这意味着程序会在一列内访问元素。
    • 缓存效果:由于每次访问时跳到下一行的元素,a[i][j]a[i+1][j] 不在同一个缓存块中。
      • 每次访问会导致缓存未命中,因为 a[i][j]a[i+1][j] 属于不同的块。
    • 结果:按列访问时,缓存命中率低,效率较差。

总结

  • 按行访问sum_array_rows)会充分利用缓存,使连续的数据加载到同一个缓存块中,从而提高缓存命中率。
  • 按列访问sum_array_cols)导致缓存不命中频繁发生,因为每次访问跳到不同的块,无法充分利用缓存。
  • 因此,二维数组的访问方式对缓存命中率有显著影响。通常情况下,按行访问效率更高,特别是在直接映射缓存或低相联度缓存中。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Zookeeper的安装与使用

一、简介 1.1、概念 ZooKeeper 是一个开源的分布式协调服务&#xff0c;主要用于解决分布式系统中的数据一致性问题。它提供了一种可靠的机制来管理和协调分布式系统的各个节点。ZooKeeper 的设计目标是简化分布式应用的开发&#xff0c;提供简单易用的接口和高性能、高稳定性…

SQLI LABS | Less-41 GET-BLIND Based-Intiger-Stacked

关注这个靶场的其它相关笔记&#xff1a;SQLI LABS —— 靶场笔记合集-CSDN博客 0x01&#xff1a;过关流程 输入下面的链接进入靶场&#xff08;如果你的地址和我不一样&#xff0c;按照你本地的环境来&#xff09;&#xff1a; http://localhost/sqli-labs/Less-41/ 本关是堆…

SpringCloud 微服务消息队列灰度方案 (RocketMQ 4.x)

目录 背景遇到的问题 RocketMQ 基础基础消息模型扩展后的消息模型部署模型相关概念点 方案对比影子Topic的方案Tag的方案UserProperty的方案影子Group的方案灰度分区的方案方案对比 灰度分区方案设计适配只有部分灰度的情况所做的功能扩展消费者&#xff08;无灰度&#xff09;…

Simulink对仿真数据进行FFT频谱分析

1 问题引入 在仿真阶段&#xff0c;经常会遇到有些仿真结果的数据需要进行频谱分析&#xff0c;如何快速便捷地操作&#xff0c;这里介绍其中一种简单的方法。主要利用 Simulink 中 Scope 显示的数据进行保存并进行 FFT 频谱分析&#xff0c;按下文操作即可。 2 实战 2.1 将…

Vue前端开发:gsap动画库

gsap它的全称是GreenSock Animation Platform&#xff0c;它是一个功能非常强大的动画平台&#xff0c;它可以对JavaScript操作的所有内容实现动画效果&#xff0c;同时&#xff0c;还解决了不同浏览器中存在的兼容性问题&#xff0c;而且速度和效率都非常快&#xff0c;全球超…

【layui】echart的简单使用

图表类型切换&#xff08;柱形图和折线图相互切换&#xff09; <title>会员数据</title><div class"layui-card layadmin-header"><div class"layui-breadcrumb" lay-filter"breadcrumb"><a lay-href""&g…

[Redis] Redis缓存机制

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…

绘制3D图

一个 3D 函数的表面图&#xff0c;其中包含向量场。 Python 代码示例&#xff0c;使用 matplotlib 和 numpy 库来绘制类似的图。 python 复制代码 import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D# 生成网格 x np.linspace(-…

【开源免费】基于SpringBoot+Vue.JS课程答疑系统(JAVA毕业设计)

博主说明&#xff1a;本文项目编号 T 070 &#xff0c;文末自助获取源码 \color{red}{T070&#xff0c;文末自助获取源码} T070&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析…

C#开发流程

注&#xff1a;检查数据库链接 设置搜索 1.新建模块文件夹 对应应用 右键-添加-新建文件夹 2.新建类 在新建模块下右键 新建-类&#xff0c;修改类名称 修改internal为public 新建所需字段&#xff0c;注意类型声明及必填设置 [SugarColumn(IsNullable false)]public strin…

【Transformer】模型输出模块处理

目录 输出处理模块步骤1. 交叉注意力后的输出向量2. 线性变换&#xff08;投影&#xff09;3. Softmax 操作4. 选择最大概率的单词5. 输出词并进入下一轮预测总结&#xff1a; 线性变换详解1. 交叉注意力后的输出向量2. 线性层的参数3. 线性变换的计算4. Softmax 转换为概率示例…

对话流式数据加载

需求&#xff1a;根据接口返回的数据进行类似打字机渲染的效果 使用的fetch 流式处理 fetch(BASE_URL/api/apps/ this.app_Id /chat-messages, {signal: this.controller.signal,method: POST,headers: {Authorization: Bearer localStorage.getItem(token),Content-Type: …

关于git使用的图文教程(包括基本使用,处理冲突问题等等)超详细

目录 用户签名,初始化git git提交流程图 提交到本地库 版本穿梭 分支操作 分支合并冲突 团队协作 github的使用 推送代码 克隆 拉取代码 团队协作冲突 团队协作之分支管理 推送分支到分支&#xff1a; 拉去远程库分支到本地库&#xff1a; 本地删除远程分支&am…

6、If、While、For、Switch

6、If、While、For、Switch 一、If 1、if-else if (boolean) {代码块 } else if (boolean) {代码块 } else if (boolean) {代码块 } else { // 默认情况代码块 }关于IDEA单元测试控制台不能输入数据的问题&#xff1a; https://blog.csdn.net/m0_72900498/article/details/…

【智谱开放平台-注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

贪心算法day05(k次取反后最大数组和 田径赛马)

目录 1.k次取反后最大化的数组和 2.按身高排序 3.优势洗牌 1.k次取反后最大化的数组和 题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 代码&#xff1a; class Solution {public int largestSumAfterKNegations(int[] nums, int k) {//如…

简简单单的UDP

前言 上一篇了解了TCP的三次握手过程&#xff0c;目的、以及如何保证可靠性、序列号与ACK的作用&#xff0c;最后离开的时候四次挥手的内容&#xff0c;这还只是TCP内容中的冰山一角&#xff0c;是不是觉得TCP这个协议非常复杂&#xff0c;这一篇我们来了解下传输层另外一个协…

安科瑞工业绝缘监测装置:保障煤矿井下6kV供电系统安全运行的关键应用——安科瑞 丁佳雯

在现代煤矿开采中&#xff0c;供电系统的稳定性和安全性是至关重要的。特别是在煤矿井下&#xff0c;由于环境复杂、湿度大、易腐蚀等因素&#xff0c;供电系统面临着严峻的挑战。为了确保供电系统的正常运行和矿工的生命安全&#xff0c;采用先进的绝缘监测装置显得尤为重要。…

OKG Research:用户意图驱动的Web3应用变革

出品&#xff5c; OKG Research 作者&#xff5c;Samuel QIN 当前加密市场的快速演变中&#xff0c;用户增长成为行业可持续发展的基石。目前主流观点在推动行业前进的路上&#xff0c;从单纯的技术探索在向更注重应用价值的方向转变。尽管近年来Web3生态系统发展迅速&#xf…

人工智能:重塑医疗、企业与生活的未来知识管理——以HelpLook为例

一、医疗行业&#xff1a;AI引领的医疗革新 随着人工智能&#xff08;AI&#xff09;技术的持续飞跃&#xff0c;我们正身处一场跨行业的深刻变革之中。在医疗健康的广阔舞台上&#xff0c;人工智能技术正扮演着日益重要的角色。它不仅能够辅助医生进行病例的精准诊断&#xf…