Cache简介

article/2025/10/18 17:36:53
1. Cache
        Cache一词来源于法语,其原意是“藏匿处,隐秘的地方”,而自从被应用于计算机科学之后,就已经成为了英语中的一个计算机体系结构专有名词。
        Sun Microsystems的前首席科学家Billy Joy,作为BSD unix,csh,vi,NFS,java,TCP/IP等的发明者,他曾经说过,在计算机科学领域,如果没有了Cache的发明,其他的一切发明都将失去意义。而正是他,将给予分页的虚拟内存系统引入了Unix,影响了之后所有的新操作系统开发。
        Cache的出现是为了解决CPU日益增长的核心时钟频率以及系统主内存日益落后的素质之间的矛盾。
        Cache的基本原理是局部性原理,局部性原理简单说起来就是在前一段时间经常用到的代码,在将来会被再次使用的几率也很高。
        我们可以想象倒水这件事,有些水桶只有一个小小的进水口,可是这样会给倒水的人造成烦恼,拿着瓢往里倒水的时候要很仔细地对准,并且还要让水流不太急以避免超出进水口的接受能力。小心地倒完一瓢再去舀一瓢,周而复始。于是有人说,要解决这个问题!就有聪明人发明了漏斗,上面的口很大,并且能够容纳一部分液体,下面的口较小保证流出的水不超出水桶口的范围。这样就可以舀一瓢水,“哗”地倒进漏斗里,歇会儿等水流差不多了再舀一瓢倒进去,这样即简化了对倒水人的技能要求(要不就得跟卖油翁一样),又提高了效率,可以让操作者节省出来时间去做其他的事情。
        Cache对CPU的意义是类似的,主存就是那个带有瓶颈的水桶,如果CPU始终要等待对内存的操作完成然后再进行下一个环节,那么在所有跟内存操作相关的指令执行时,CPU就自动降为接近内存的速度。也许你会认为很多指令是寄存器指令,内存读写在整个程序中所占的比例并不大,但是请不要忘记很恐怖的一点是,所有的指令都在内存中,也就是说每执行一条指令都要去读内存。有了这个前提,我们可以想象,在程序执行的时候,CPU会随时随刻地从内存中读取代码,整条总线会被CPU占住,这样的话总线上的其他master(比如说DMA控制器,I2C-Slave等)就将全部受到影响,由此可见没有Cache的结果就将是灾难性的。有些Cache还会跟读写FIFO紧密配合,不过目的都是一致的,解决内存瓶颈问题。有人可能会有疑问,多数ARM7内核的芯片是没有Cache的,为什么依然能够运行得很快,这是因为IC designer在设计总线结构时动了手脚,将CPU取指的总线同其他部分总线隔离,以避免CPU对其他总线设备的干扰。
        Cache按写操作模式来分又分为写穿(write through)和写回(write back)两种,由于写穿模式的效率要比写回模式低很多,所以目前绝大多数应用中都是采用的写回模式。
        按用途来说Cache分为ICache和DCache,分别作为指令和数据缓存,在某些老的架构中,指令和数据混用一个Cache。
        Cache的最小操作单位是行(line),也就是说每次cache的操作必须是以32个字节为单位,不能只选择其中某个字节。而且这32个字节数据的首地址必须是32字节对齐的。每一行的大小并不是一定的,在其发展历史中曾经有过很多种选择,目前比较通用的一个选择是每行32个字节,对于32位RISC来说就是4个word。
        Cache的每一行有tag和index域用来寻址,这个tag和index的功用会在后面详细介绍。
        按寻址方式分,Cache可以分为全相联映射,直接映射和多路组相联映射Cache,所谓的全相联映射指的是任意一行地址中的数据可以放到任意一个Cache line中,CPU都可以根据tag和index准确地寻址到。
        举个例子来说明这种方式,比如说从地址0x3100 0000到地址0x3100 001F的这32个字节的数据,如果想做到它可以放到任一行中,那么我们就必须得保证针对于任一行数据,都要提供给它唯一的一个标识符,也就是说在32位系统中,由于地址是32位的,行本身是32个字节,表示行内偏移占用了5位,那么必须得提供27位的标识符(针对本例,这个标识符就得是0x188000),才能保证任一行数据可以放置到任一Cache行中,并能够被正确寻址。
        而全相联Cache的问题不仅仅是需要硬件连线比较多,而且它的效率比较低,在极端情况下可能找一个数据需要寻址整个Cache。


 

            图一  全相联Cache的结构示意图


直接映射Cache
        为了简化Cache的设计并提高效率,提出了直接映射的概念,直接映射Cache中,对于任一地址,它在Cache中有且只有一个line会与之匹配,并且这个line的index是固定的,大大简化了CPU对Cache的操作和寻址流程。
        还是拿上面那个地址为例,假设Cache是4k bytes大小的,每一行还是32 bytes,那么0x3100 0000这个地址就肯定出现在Cache的第一行(或者说index为0),0x XXXX X020这个地址出现在Cache的第二行(index为1), 0x XXXX Xfff这个地址就一定出现在Cache的第128行(index为127),这样的话对于任一地址,CPU只需到相应的行上去检查tag是否符合来决定是hit还是miss。
 
            图二    直接映射Cache的结构示意图
      
         但是这种直接映射的方式也出现了另外一个问题,我们写一个简单的程序来说明(假设CPU内核对读写内存的策略一样,都要经过Cache):
Int demo_copy(int* dst, int* src, uint length)
{
    int i = 0;
    
    for(i = length; i > 0; i --)
{
*dst = * src;
    dst ++;
    src ++;
}
}
        而如果dst和src的差恰好是4k的整数倍(假设Cache是4k大小),而这个拷贝的动作实际上是首先将src的数据load进来,然后再store进dst里面去,而他们的在Cache中的index是一样的,就导致了Cache行的频繁失效,极大降低了系统的效率。有些人可能认为这只是一种特例,但是随着系统越来越庞大,指令和数据发生这种巧合的可能性大大增加,于是必须在设计中考虑对这种情况的处理。
        多路组相联Cache的出现就是为了应对这种状况,多路组相联的概念就是将多个并行的直接映射Cache集成到一起,这样对于一个index就会有多个行与之相对应,比较每行的tag是否与想要的地址相符合,这样就会大大增加命中的几率,避免了一小段程序中频繁Cache失效的问题。
 


            图三  组相联直接映射Cache的结构示意图


         即使是多路组相联的Cache也面临着替换的问题,随着系统运行时间的增加,所有的Cache行都会被占满,这时再有新地址的数据请求进来,就要将已有的数据替换出去,而将哪一组的相应行替换出去又成为了一个问题,过去采用的方式有轮转替换,随机替换等,目前较多采用的方式被称为LRU(least recently used),也就是将最近最少使用的行替换掉,这也是对局部性原理的一种应用。

        按照工作原理来分,Cache又有physical index physical tagged, virtual index virtual tagged, physical index virtual tagged等几种分法,我们来一一了解一下。
        Physical index physical tagged是一种最容易理解的操作方式,Cache针对物理地址进行操作,简单粗暴,而且不会有歧义。但是这种方式的缺陷也很明显,在多进程操作系统中,每个进程拥有自己独立的地址空间,指令和代码都是以虚拟地址的方式存在,CPU发出的memory access的指令都是以虚拟地址的方式发出,这样的话,对于每一个memory access的操作,都要先等待MMU将虚拟地址翻译为物理地址,这是一种串行的方式,效率较低。
        Virtual index virtual tagged是纯粹用虚拟地址来寻址,这种方式带来了更多的问题,每一行数据在原有tag的基础上都要将进程标识加上以区分多个进程之间的相同地址,而在处理共享内存时也比较麻烦,共享内存在不同的进程中的虚拟地址不相同,如何同步是个问题。
        现在比较多的是采用virtual index physical tagged的方式,virtual index的含义是当cpu发出一个地址请求之后,低位地址去和Cache中的index匹配, physical tagged是指虚拟地址的高位地址去和mmu中的页表匹配以拿到物理地址(index和取物理地址这两个过程是并行的),然后用从MMU中取到的物理地址作为tag(或者tag的一部分)去和Cache line的tag位匹配,这样既保证了同一地址在Cache中的唯一性(有个例外,Cache alias)又能将MMU和Cache并行工作,提高了效率。这种方式带来的唯一问题就是Cache alias,Cache alias主要发生在Cache大小同内存页框大小不一致时,比如说每路Cache的大小是8k,而现在较为常用的页框大小是4k,这两个数字说明的问题分别是这样的:
        页框大小为4k意味着MMU在划分虚拟空间时是以4k为粒度,每一个4k对齐的内存区域作为内存分配的最小单位,于是就有了这样的结果,虚拟地址和物理地址的低12位是相同的,因为低12位地址是作为其在4k页框内的偏移,不管它的虚拟地址是什么,它在4k页面内的偏移是一定的。
       Cache大小为8k,意味着Cache index是用依据13位地址来运算的,而如果以虚拟地址来寻址Cache,低13位中就包含了一位虚拟地址,所以这种方式称为virtual index。问题出现了,一个物理地址当它被不同进程使用时,由于MMU分页机制仅能保证其低12位相同,那么第13位很有可能是不同的,这样就造成了一个物理地址在Cache中有两个副本,可能会造成同步问题。
        针对于Cache alias问题,目前的方案是由操作系统来保证,对于同一物理地址在不同进程空间的虚拟地址,他们的虚拟地址的差一定是Cache大小的整数倍,也就是说他们的第13位一定是相同的。同时已经有些CPU厂商在开发监视模块,试图在硬件层面解决类似的同步问题。
图例说明:
龙芯2F 一级指令Cache 采用虚地址索引和物理地址标志的四路组相联结构
 
        如图 所示,地址的低14位被用作指令Cache的索引。其中13:5位用于索引512个项。其中每个项中又包含四个64位的双字,使用4:3位在这四个双字中进行选择。 
        当对Cache索引时,从Cache中取出四个块中的Data和相应的物理地址Tag,同时,高位地址通过指令TLB(Instruction Translation Look-aside Buffer,简称ITLB)进行转换,将转换后的地址与取出的四个组中的Tags进行比较,若存在一个Tag与其匹配,则使用该组中的数据。这就被称为一次“一级Cache命中(Hit)”。若四组的Tag都不与其匹配,那么中止操作,并开始访问二级Cache。这就被称为“一级Cache失效(miss)”。


写策略
1:命中,又分两种策略
(1)写回法:只写本级Cache,暂时不写数据到主存或下一级Cache,等到该行被替换出去时,才将数据写回到主存或下一级Cache。
(2)写直达:写本级Cache,同时写数据到主存或下一级Cache,等到该行被替换出去时,就不用写回数据了。
2:失败,又分两种策略
(1)按写分配,又分两种:[1]先写数据到主存或下一级Cache,并从主存或下一级Cache读取刚才修改过的数据,即:先写数据,再为所写数据分配Cache line;[2]先分配Cache line给所写数据,即:从主存中读取一行数据到Cache,然后直接对cache进行修改,并不把数据到写到主存或下一级Cache,一直等到该行被替换出去,才写数据到主存或下一级Cache。

(2)写不分配:直接写数据到主存或下一级Cache,并且不从主存或下一级Cache中读取被改写的数据,即:不分配Cache line给被修

改的数据。

读策略
1:命中,则从Cache中读相应数据到CPU或上一级Cache中。
2:失败,则从主存或下一级Cache中读取数据,并替换出一行数据,通常采用LRU算法

http://chatgpt.dhexx.cn/article/g1tFsyAG.shtml

相关文章

Redis入门完整教程:CacheCloud是什么?

如果让你去运维大规模的Redis节点,例如数千个 Redis节点、数百台机器、数百个业务支撑,会遇到什么问题吗?很明显就 是缺少一个好的可视化运维平台。本节首先分析如果没有好的运维平台可能 存在的问题,接着介绍Redis开源私有云平台…

CacheCloud详解(一)----------CacheCloud搭建(Redis云平台)

目标: redis作为流行的缓存数据库,被众多企业使用,但是对于中小型企业来说,日益增多的redis服务器,如何管理是个问题。本系列文章就搜狐视频开源的CacheCloud云平台进行深入讲解。通过从安装到源码讲解,让…

分享kubernetes部署:cachecloud部署说明

cachecloud部署 cachecloud是搜狐视频(sohutv)Redis私有云平台 已省略~ 挑选一台服务器部署cachecloud-web 将cachecloud-web打成war包,可以在服务器上打包,也可以在本地打包,这里举一个在服务器上打包的例子。 将源代码下载到/opt下 已省略~…

CacheCloud搭建(Redis云平台)

下载源代码启动Server 1、初始化MySQL数据库2、启动(本地) 登录系统Redis 机器环境初始化普通用户注册应用申请客户端连接 在中小型互联网公司里面,对于运维使用的监控系统不是很完善。今天介绍一下 CacheCloud,是搜狐视频开源的 …

【Linux】Cachecloud安装部署图文并茂

搭建环境 cachecloudJDKMavenMySQLRedis是是是是是 cachecloud安装 说明:安装cachecloud之前需要在机器上安装maven、jdk、mysql软件的步骤不做说明,测试软件安装路径为:/usr/local。 下载 https://github.com/sohutv/cachecloud 下载CacheCloud-mas…

Redis监控运维平台-CacheCloud

一、CacheCloud 1、出现问题 当Redis达到一定规模,容易出现以下问题: 运维部署成本高,手动部署,容易出现错误。实例碎片化,机器利用率较低,可能出现大量闲置资源。监控,统计,管理…

Redis入门完整教程:CacheCloud快速部署

13.2.1 CacheCloud环境需求 安装部署CacheCloud需要以下环境: JDK7:CacheCloud使用Java语言开发,并使用了JDK7的一些特性。 Maven3:CacheCloud使用Maven3作为开发构建工具。 MySQL5.5:CacheCloud需要Redis的相关元信息…

Redis入门完整教程:CacheCloud运维功能

13.6 运维功能 CacheCloud作为Redis的运维工具,包含了Redis日常运维的常用功能, 本节将对如下功能进行介绍: 1)应用运维:Redis节点的上下线、手动故障转移、配置管理、扩容 等。 2)接入已存在的Redis&…

一文解决IDEA中文乱码问题

✅作者简介:热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏:JAVA开发者…

idea中中文字体设置

此次设置idea中字体为中文雅黑字体 1.找到安装的idea路径中jdr的lib文件进去 E:\IntelliJ IDEA 2019.2\jbr\lib2.创建文件名及格式为fontconfig.properties的文件 3.复制以下代码进文件 # Versionversion1# Component Font Mappingsallfonts.chinese-ms936Microsoft Yahei a…

IDEA--解决IntelliJ IDEA中文乱码问题

1.首先是编辑器的乱码,这个很好解决,file->settings->appearence里面有个Name设置成支持中文的字 体(这个很重要) 同样还要再settings中的Eidtor->File Encodings里面设置字体编码格式,一般都是UTF-8,GBK什么的也行。 2.…

彻底解决Intellij IDEA中文乱码问题

关于JAVA IDE开发工具,Eclipse系列和Intelli IDEA是大部分公司的主要选择,从开发者的选择角度,Intellij IDEA似乎比Eclipse系列更受欢迎一些。当我们使用Intellij IDEA开发时,我们发现出现中文乱码问题,造成中文乱码的…

彻底解决idea中文乱码问题(不易发现的点,jdk问题)

这里提出一个由于jdk问题导致的中文乱码问题。 1.Setting中的各项都设置为utf-8 2.这里设置成这样,极低概率是这里的问题 3.右下角设置utf-8 4.Help-Edit custom VM options后面加上Dfile.encodingUTF-8 5.idea安装目录的bin文件中两个文件idea.exe.vmoptions 和…

IDEA:IDEA中文翻译插件的安装与使用

IDEA安装中文插件 一、打开设置 二、安装插件 三、插件设置 设置自己喜欢的翻译引擎 勾选翻译文档 四、效果 鼠标光标放上去就可以查看中文文档了 Shift Ctrl O:可以弹出翻译框 选中要翻译的文本,右键选择翻译或者使用快捷键:Shift Ctr…

2020版的idea中文插件安装

2020版的idea中文插件安装 1. 打开idea,进入创建project界面 2.选择中文插件 3.搜索Chinese插件 4.重启IDE 5.重新打开就是中文界面

idea无法识别中文

开始修改idea之前,建议先查看自己代码的编码格式,用Notepad打开之后,点击上方编码,就能看到编码格式。我是因为git的原因,导致拉下来的代码是默认编码,一个文件一个格式。修改git编码的方法自行百度。 在解…

IDEA更改中文字体

初始: 效果: 更改:file-settings,左侧搜索框中直接输入font,然后如下图,将字体改为SimHei,应用保存即可

IDEA中文乱码五种解决方法

1.IDEA安装目录找到 打开文件,末尾添加-Dfile.encodingUTF-8 2.IDEA设置 3.设置VM options为-Dfile.encodingUTF-8 4.打开在末尾添加-Dfile.encodingUTF-8 5.在.idea的文件夹里面有个encodings.xml 的文件,除了UTF-8 的都删了

Mac如何设置intellij idea中文

1、点击菜单栏的「IntelliJ IDEA」,再点击「Preferences…」打开软件的偏好设置 2、点击左侧导航的「Plugins」,在右侧的「Type / to see options」处输入「chinese」,找到「Chinese (Simplified) Language」点击「Install」 3、安装完成后点击「Restart…

解决IDEA中文字体大小不一

具体问题:中文显示不正常 问题原因: idea中的默认字体Consolas中没有中文字体,与IDEA版本有关,比如IDEA2019.2就容易出现这个问题。 解决方法: 依次点击 File > settings > Editor > Font 中…