页表和cache

页表基本原理

页表主要用来将虚拟地址映射到物理地址,在使用虚拟地址访问内存时,微处理器首先将虚拟地址拆分成页号和页内偏移量,然后使用页号在页表中查找对应的物理页框号,将物理页地址加上页内偏移量,得到最终的物理地址。
32位系统中,当页大小为4KB时,如要覆盖4GB内存,需要1M个页项,如果页项是连续的,每个页项占4字节的话,页表总共需要4MB。

虚拟地址组成:

20位12位
页号页内偏移

4MB如果在进程运行前都准备好,对于进程来说空间占用太大了。可以考虑用多级页表,实现动态分配,假如分两级,每级各占10比特:

10位10位12位
页目录项(Page Directory Entry,PDE)页表表项(Page Table Entry,PTE)页内偏移(Page Offset)

一个页目录项可以覆盖210个页,也就是1MB内存。

cache基本原理

cache是为了缓存经常用到的内存数据。
先不考虑缓存的是物理地址还是虚拟地址。

cache以cache line为单位进行缓存,如果cache line是8字节,那这8字节会一起加载到cache中,要失效也是一起失效。

直接映射缓存

下图是一个64字节大小的cache,data array中每行是一个cache line,cache line有一个D位,表示数据是否dirty。
直接映射缓存

cache将地址分为3部分:tag index offset。

offset是地址在cache line中的偏移,该例中cache line是8字节,所以需要3比特。
index是地址在data array中的索引,该例中cache size是64字节,cache line是8字节,所以data array有8行,index需要3比特。

地址 0x14 和 0x654 都映射到cache中一个位置,那怎么区分存储的是哪个数据呢,靠比较tag。
1个tag对应1个cache line,所以offset位不需要考虑,对比tag的时候已经定位到具体的行了,index位也是固定的了,所以tag只需要记录除offset和index外的位,该例中是32-3-3=26位。tag array和data array容量相同,并且一一对应,如果tag是 0x19,就表示当前cache line的起始地址是 0x650。

26位3位3位
tagindexoffset

我们可以从图中看到tag旁边还有一个valid bit,用来表示cache line中数据是否有效。当系统刚启动时,cache中的数据都应该是无效的。所以,上述比较tag确认cache line是否命中之前还会检查valid bit是否有效。只有在有效的情况下,比较tag才有意义。如果无效,直接判定cache缺失。

图中这种方式叫直接映射缓存,它对地址的缓存是循环的,0x00,0x40,0x80…开始的8字节都映射到同一个cache line中。
系统启动后,当我们访问 0x00 地址时,cache会缺失,然后数据会从主存加载到cache中第0行cache line。当我们访问0x40地址时,依然索引到cache中第0行cache line,由于此时cache line中存储的是地址0x00地址对应的数据,所以此时依然会cache缺失。然后从主存中加载0x40地址数据到第0行cache line中。同理,继续访问0x80地址,依然会cache缺失。这就相当于每次访问数据都要从主存中读取,访问0x40地址时,就会把0x00地址缓存的数据替换。这种现象叫做cache颠簸(cache thrashing)。

多路组相连缓存

针对这个问题,引入多路组相连缓存。我们首先研究下最简单的两路组相连缓存。
两路相连缓存
data array中竖着叫路,横着叫组。将64字节cache分成两路,之前data array有8行,现在有两个data array,所以只有4行了,index也只需要2比特了。tag还是占除index和offset外的所有位。
根据index找到是哪组,然后将组内的所有cache line对应的tag取出来和地址中的tag部分对比,如果其中一个相等就意味着命中。就像链表一样。
据说会降低cache颠簸的频率。

直接映射缓存是组相连缓存的一种特殊情况,每个组只有1个cache line,它只有1路。全相连缓存是另一种特殊情况,它只有1组。

cache size = 2index位数 * 路数 * 2offset位数 = 路数 * 2(index位数+offset位数)

cache组织方式

PIPT和VIPT

如果cache缓存的是物理地址,称为PIPT,Physically Indexed Physically Tagged。CPU发出的虚拟地址经过MMU转换成物理地址,再将物理地址发往cache控制器查找确认是否命中cache。

如果缓存的是虚拟地址,称为VIVT,Virtually Indexed Virtually Tagged。虚拟地址直接送到cache控制器,如果cache hit,直接从cache中返回数据给CPU,如果cache miss,则把虚拟地址发往MMU,经过MMU转换成物理地址,从主存读取数据。

缓存命中的时候,相比PIPT,VIVT少了虚拟地址到物理地址的转换。但是VIVT有歧义和别名的问题。
歧义是指不同的数据在cache中具有相同的tag和index。假设A进程虚拟地址0x4000映射物理地址0x2000,B进程虚拟地址0x4000映射物理地址0x3000。当A进程运行时,访问0x4000地址会将物理地址0x2000的数据加载到cache中。当切换到B进程的时候,B进程访问0x4000会怎样?当然是会cache hit,B进程本来想得到物理地址0x3000对应的数据,但是却由于cache hit得到了物理地址0x2000的数据。进程切换的时候flush cache可以避免歧义问题。
同一个物理地址的数据被加载到不同的cache line中就会出现别名现象。比如虚拟地址0x2000和0x4000(二者在不同的cache line中)都映射到相同的物理地址0x8000,这意味着进程既可以从0x2000读取数据,也能从地址0x4000读取数据。这是由页表的多对一导致的。一个解决方法是,让映射到同一物理地址的虚拟地址,在cache中也有相同的地址。但这只对直接映射缓存有效,细节后面会详细说。

VIPT

为了提升cache查找性能,我们不想等到虚拟地址转换物理地址完成后才去查找cache。因此,我们可以使用虚拟地址对应的index位查找cache,与此同时(硬件上同时进行)将虚拟地址发到MMU转换成物理地址。二者都完成时,比较cache line对应的tag和物理地址,以此判断是否命中cache。我们称这种方式为VIPT(Virtually Indexed Physically Tagged)。

cache line对应的tag可以使用完整的物理地址。此时不会有歧义问题,比如之前例子中,B进程访问0x4000时会发现tag不同,于是cache miss。由于物理地址和虚拟地址的低12位是相同的,cache line对应的tag可以只存物理地址的高20位,对比的时候将其加上地址的低12位便是完整的物理地址了。

别名问题是因为虚拟地址和物理地址多对一导致的,只要物理地址相同的虚拟地址,也在相同的cache地址中就不会有问题。也就是让这些虚拟地址的index位和offset位相同。
当index位和offset位之和不大于12时,各个虚拟地址的低12位和物理地址的低12位本就相同,所以index位和offset位也必然相同,此时不存在别名问题。
当index位和offset位之和大于12时,为同一物理地址分配多个虚拟地址时,则要保证虚拟地址的index位和offset位相同,可以让其全为0,也就相当于按“cache size/路数”对齐了。

这种方法在VIVT中只对直接映射缓存有效。因为在多路组相连缓存中,对应同一物理地址的多个虚拟地址会映射到同一组中,如果是Virtually Tagged,因为tag不同,它们会定位到不同的路中。

PIVT

不存在,因为PIVT方式首先要通过MMU转换成物理地址,然后才能根据物理地址index域查找cache,既然都有了物理地址,干嘛不直接用PIPT。

参考

Cache的基本原理
Cache组织方式

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Rust核心功能之一(所有权)

目录 1、什么是所有权? 1.1 所有权规则 1.2 变量作用域 1.3 String 类型 1.4 内存与分配 变量与数据交互的方式(一):移动 变量与数据交互的方式(二):克隆 只在栈上的数据:拷贝…

如何使用Pyarmor保护你的Python脚本

目录 一、Pyarmor简介 二、使用Pyarmor保护Python脚本 1、安装Pyarmor 2、创建Pyarmor项目 3、添加Python脚本 4、配置执行环境 5、生成保护后的脚本 三、注意事项与未来发展 四、未来发展 五、总结 本文深入探讨了如何使用Pyarmor工具保护Python脚本。Pyarmor是一个…

k8s的安装部署,详细过程展示(保姆级安装教程)

k8s应用部署方式演变 在部署应用程序的方式上,主要经历了三个时代: 传统部署:互联网早期,会直接将应用程序部署在物理机上 优点:简单,不需要其它技术的参与 缺点:不能为应用程序定义资源使用…

Python 的 datetime 模块

目录 简介 一、date类 (一)date 类属性 (二)date 类方法 (三)实例属性 (四)实例的方法 二、time类 (一)time 类属性 (二)tim…

UDP网络编程

一)熟悉TCP/IP五层协议: 1)封装:就是在数据中添加一些辅助传输的信息; 2)分用:就是解析这些信息 3)发送数据的时候,上层协议要把数据交给下层协议,由下层协议来添加一些信息 4)接收数据的时候,下层协议要把数据交给上层协议&#…

Python初学者软件以及如何安装和配置,新手入门必看系列。

文章目录 前言一、Python软件二、集成开发环境(IDE)1.PyCharm2.Spyder3.IDLE 三、包管理工具四、使用Python虚拟环境总结Python技术资源分享1、Python所有方向的学习路线2、学习软件3、精品书籍4、入门学习视频5、实战案例6、清华编程大佬出品《漫画看学…

探索云世界的无限可能

文章目录 每日一句正能量前言云计算的定义和现状云计算能做什么?云计算市场的新特征需求方向:云计算的基础服务已经稳固,行业解决方案是新的发力点模式方向:分布式云模式方向:边缘计算是一朵新的云技术方向&#xff1a…

AMESim 2021安装教程

主要是AMESim的安装 写在前面,由于项目需要,需要自学AMESim,因此需要安装这个软件,目前仅仅安装使用,还不涉及到与MATLAB的联合仿真,老板说用 RT LAB半实物仿真平台,但是简单搜了一下&#xff0…

ASUS华硕灵耀X2 Duo UX481FA(FL,FZ)_UX4000F工厂模式原装出厂Windows10系统

下载链接:https://pan.baidu.com/s/1sRHKBOyc3zu1v0qw4dSASA?pwd7nb0 提取码:7nb0 带有ASUS RECOVERY恢复功能、自带所有驱动、出厂主题壁纸、系统属性专属LOGO标志、Office办公软件、MyASUS华硕电脑管家等预装程序所需要工具:16G或以上…

麒麟KYLINIOS软件仓库搭建03-软件仓库添加新版本的软件包

原文链接:麒麟KYLINIOS软件仓库搭建03-软件仓库添加新版本的软件包 hello,大家好啊,今天给大家带来麒麟桌面操作系统软件仓库搭建的文章03-软件仓库添加新版本的软件包,本篇文章主要给大家介绍了如何在麒麟桌面操作系统2203-x86版…

Vite项目的初体验 - 非Vite脚手架版本

开箱即用 (out of box): 无需做任何的配置,就可以用vite来帮助我们处理构建工作。 前提 :node 版本 > 12.0.0,使用 npm 进行依赖管理。 本文的案例,从0到1的,一步一步的体会vite的作用。 本文…

图解三傻排序 选择排序、冒泡排序、插入排序

&#xff08;1&#xff09;选择排序 // 交换 void swap(int arr[], int i, int j) {int tmp arr[i];arr[i] arr[j];arr[j] tmp; }// 选择排序 void selectionSort(int arr[],int len) {if (len < 2) return;for (int minIndex, i 0; i < len - 1; i) {minIndex i;f…

WPS的JS宏基础(一)

基础知识 1、简单的第一个宏 //注意function只能全部用小写 function demo(){alert("你好!") }2、录制宏生成工资条 function 使用录制宏自动生成代码以JS宏为例()//使用相对引用 {Selection.Copy(undefined);ActiveCell.Offset(5, 0).Range("A1:M4").I…

Ubuntu22.04 下 NFS 相关问题与完整配置(客户机 MacOS)

categories: [Linux-Shell] tags: Linux NFS 写在前面 最近折腾一下 NFS, 先白嫖一顿华子云的 1 个月服务器, 2C4G 感觉不错了, 但NFS 配置起来还是有点难度, 主要还是随机分配的端口配置方面比较恶心. server环境: 华为云 2C4G Ubuntu22.04 client环境: MacOS M1 with brew …

排序算法的分析及实现

目录​​​​​​​ 1. 排序 1.1. 排序的概念 1.2. 排序的稳定性 1.3. 内部排序和外部排序 2. 直接插入排序 2.1. 直接插入排序 2.2. 直接插入排序的两种情况 1. 情况一 2. 情况二 2.3. 直接插入排序的单趟排序 2.4. 直接插入排序的完整实现 2.5. 直接插入排序的时…

接收表单数据

如果您尝试按下提交按钮&#xff0c;浏览器将显示“Method Not Allowed”错误。这是因为到目前为止&#xff0c;前一节中的登录视图函数完成了一半的工作。它可以在网页上显示表单&#xff0c;但是还没有逻辑来处理用户提交的数据。这是Flask-WTF使工作变得非常简单的另一个领域…

selenium xpath定位

selenium-xpath定位 <span style"background-color:#2d2d2d"><span style"color:#cccccc"><code class"language-javascript">element_xpath <span style"color:#67cdcc"></span> driver<span styl…

有什么可以自动保存微信文件的方法么?

8-3 本文要介绍的方法&#xff0c;可以自动帮你保存微信上收到的文件型数据&#xff0c;比如文件、图片、视频&#xff0c;如果你的工作需要每天或者经常保存大量的从微信收到的文件型数据&#xff0c;也许本文适合你&#xff0c;本文介绍的工具&#xff0c;对微信多开也有效果…

Git安装配置保姆级教程和Git创建仓库的基本原理和常用命令

目录 前言 一、Git简介 1.Git 与 SVN 区别点 2.Git的介绍 3.Git 工作流程 4.Git 工作区、暂存区和版本库 二、Git安装配置 1.Linux 平台上安装 2.Windows 平台上安装 三、Git 创建仓库和下载 1、首先需要注册一个gitee账号 2.git初始化并提交到远程仓库 3.另一用户…

STM32 蜂鸣器介绍 配置 播放音节

蜂鸣器一般被分为两类&#xff1a;有源蜂鸣器和无源蜂鸣器。其中源是振荡源。有源蜂鸣器内部有振荡电路&#xff0c;可以把直流电源转换为一定频率的脉冲信号。因为它一直输出一定的频率&#xff0c;我们无法改变频率&#xff0c;所以声音只有一种&#xff0c;我们只能通过电源…