高速缓存(cache)存储器:

这里先说明一下(高速缓存)cache和(高速缓冲)buffer的区别:
buffer主要作用是在一定程度上减少对IO设备访问的次数,可以起到流量整形的作用,也提升了系统的性能,毕竟IO操作和内存和cpu的处理速度差距还是很大的,比如下载一个文件,是积攒到一定量才写回磁盘,而不是下载一个字节写回一个字节,这样过不了多久,磁盘就损坏了。
cache主要作用是缓解处理数据的两端速度不匹配这种情况带来的时间上的浪费,这样做就加快了访问速度。比如大家都知道的cpu和内存之间的速度差异就特别大,所以需要cache缓存数据,以便提高速度。
总之一句话,buffer主要解决了空间上的问题,而cache主要解决了时间上的问题。

众所周知,寄存器和内存之间读写速度的差距是很大的,而内存和磁盘之间的读写速度差距也很大。当内存需要传数据给寄存器,假如有这样一个读写速度处于寄存器和内存之间的东西,可以帮忙存储内存要传的数据,然后再把这些数据传给寄存器,这样不就提高了速度了吗。高速缓存存储器就是这样一个东西,在两端读写速度差距很大时,就插入一个高速缓存存储器,这样的思想就形成了存储器层次结构。引用《CSAPP》书中的图:

而图中每一层都是下一层的缓存,也就是说,层次结构的每一层都缓存来自较低一层的数据。
接下来介绍块的概念,缓存存储器是分块的,数据总是以块为基本单位在每一层之间传递,块的大小只在相互传递的两层之间是相同的,并且一般是越位与底层的块大小越大,这样就弥补了底层存储器每次访问的所花销的大量的时间。

数据是缓存好了,但是不一定缓存的数据就是需要的数据。

所以取数据时也分缓存命中和缓存不命中。

缓存命中

意思就是第k+1层需要的数据就是第k层缓存好的,直接读取就行了。

缓存不命中

意思就是第k+1层需要的数据在第k层中没有。发生缓存不命中之后,会把该数据缓存在第k层中,如果当前有空余的空间还好,可以直接缓存,但是如果没有空间就会导致替换的发生,意思就是覆盖第k层中的某一个块,当然,这个不是随便替换的,也会使用适用于当前情况的替换策略,可以随机替换、也可以根据在某个时间段内引用次数最少的块来替换、还有替换掉最长时间没有使用的块,这些替换策略有的简单,有的复杂,复杂一点的,相对而言更加合理,但是还要考虑到复杂的替换策略所需要的代价。像磁盘这种读写速度很慢的存储器,就可以使用复杂一点的替换策略,替换策略所花的代价远比再次发生不命中所花的代价小。

缓存不命中也分为几大类:

  1. 强制不命中:即如果第k层的缓存是空的,那么一定就会不命中了。
  2. 冲突不命中:假如发生了不命中之后,数据是会被缓存在第k层的,那么缓存的位置该怎么选择呢,如果使用随机放置的方法,下次找起来不太方便,所以硬件通常将第k+1层中某个块限制在第k层中的某个子集中(采用映射),比如进行取余运算选择缓存位置,那么块号取余之后数字相同的块就会缓存到同一个地方,就发生了冲突,举个例子,假如进行mod3运算,第k+1层的块号为4、7的数据块需要缓存,这样都会缓存到第k层的块号为1的位置上。还有一个很糟糕的现象,即按照4、7、4、7这样的顺序来读数据,每次都会发生冲突不命中,就算第k层的空间还够,这种现象称为抖动。
  3. 容量不命中:当第k层的容量不足以缓存下需要缓存的数据时,就称为容量不命中。

另外,在存储器层次结构中,管理缓存的对象也不完全相同。比如编译器就管理寄存器,而SRAM的缓存由硬件管理,主存(DRAM)由操作系统和地址翻译硬件mmu管理。

前面都只介绍了一下缓存的大致的概念,而到底是怎么找寻数据对应的缓存的,以及高速缓存存储器的结构是什么,都还不知道,下面就进行说明。

这里继续引用《CSAPP》书中的图:

考虑到一个计算机系统,其中每个存储器地址有m位,形成M=2^m个不同的地址。如图6-27a所示,这样一个机器的高速缓存被组织成一个有S=2^s个高速缓存组(cache set)的数组。每个组包含E个高速缓存行(cache line)。每个行是由一个B=2^b字节的数据块(block)组成的,一个有效位(valid bit)指明这个行是否包含有意义的信息,还有t=m-(b+s)个标记位(tag bit)(是当前块的存储器地址的位的一个子集),它们唯一地标识存储在这个高速缓存行中的块。

上面是《CSAPP》书中对图中的各数值的讲解。其实我们不用太关注每个占多少位什么的,只用知道,高速缓存分成组,每组又包含很多行,每行由有效位和标记位以及数据块组成的即可,这样不知道字母对应的哪个项再查看即可。
先从组开始分析,高速缓存分成了多个组,每组包含多行,分组可以得到数据缓存的大概位置,从6-27b图中的可以得出,组索引专门就是用来找到数据缓存的相应的组的。
再看行,有效位是用来标记该行有缓存数据,标记位是用来匹配组内的具体的哪一行的,见图6-27b图,前t位也是是标记位,我们通过组索引找到数据对应缓存的那一组,再根据标记位找到数据缓存在哪一行的,最后通过块偏移找到数据的起始字节。
是不是感觉很简单。

根据每个组的高速缓存行数高速缓存可以分为直接映射高速缓存(每组只有一个高速缓存行)、E路组相联高速缓存(每组有E个高速缓存行)、全相联高速缓存(只有一个组)

直接映射高速缓存:

由于每组只有一个高速缓存行,所以只要通过组索引就可以得到是哪一行了,但是这并不代表数据就缓存在这一行中,还要查看有效位是否置位,并且要对比标记位是否相同,这几个条件都满足了,才代表数据就缓存在该行中,最后通过块偏移找到数据的起始字节并取出。见图:

当发生不命中时,由于每组只有一行,所以直接用新取出的行替换当前行就行了。

组相联高速缓存:

和直接映射高速缓存寻找组一样,都是通过组索引寻找,但是找到高速缓存行就不一样了,因为组相联高速缓存每组有多行,所以高速缓存需要寻找该组内和地址的标记位相同的标记位。

发生不命中时,就需要使用之前我们提到的替换策略了。

全相联高速缓存:

全相联高速缓存中,地址就没有组索引这一项了,因为并不需要了,只有一个组了,其它的步骤和组相联高速缓存一样。由于全相联高速缓存只有一个组,那么当高速缓存行多了的时候,找起来其实是非常费力的,所以它只适合做小的高速缓存,比如虚拟存储器系统中的翻译备用缓存器TLB。

影响一个高速缓存的性能有很多,比如:

1. 高速缓存的大小:大了可以提高命中率,但是会增加命中时间。

2. 块的大小:大了可以利用程序可能存在的空间局部性,提高命中率。由于块很大,所以传送的时间也增加了,如果发生了不命中,代价就很大了。

3. 相联度:大了可以降低高速缓存发生冲突不命中时出现抖动的可能性,但是会增加命中时间(因为要查标记位),以及替换策略的复杂性也增加了。

4. 写策略:之前没有说明写策略,因为它很困难也充满了细节,这里简单说明一下:当高速缓存中更新了一个数据时,要接着更新低一层中该数据时,就发生了写,如果采用直写策略,即直接更新该数据,但是这样虽然简单,但是每次都会在总线上传输,就算可能该数据不会被使用,还有一种策略称为写回,即当前层的这个数据对应的行要被替换了,才更新低一层的该数据,这样可以降低总线流量,但是复杂性变高了,因为不得不在高速缓存行上添加一位是否被修改的位。如果写不命中时,有种方法叫写分配,即加载相应的低一层中的块到高速缓存中,然后更新这个高速缓存块。那么写策略会给高速缓存带来什么影响呢。如果采用直写,传送数据的时间就增加了,所以在低层次的存储器中,一般采用写回。

小结:

高速缓存存储器的缓存机制差不多就说到这了,我们了解了大概的思想以及如何去寻找缓存和缓存不命中时会发生什么。但是其实其中还有很多细节,需要自己去查阅相关资料以及细读《CSAPP》才能发现。比如,为什么组索引不采用高位地址,而是中间的地址?这是因为如果采用高位地址,会导致连续的块被映射到相同的高速缓存块。还有块和行的区别是什么?行是高速缓存中存储块以及其它信息的容器,块是高速缓存存储器和下一层存储器传输的基本单位。

为了尽量让缓存命中,在程序中就应该尽量提高空间局部性和时间局部性。这两者是什么,以及怎么提高,后面再写博文进行说明。

高速缓存(cache)存储器相关推荐

  1. 例说STM32F7高速缓存——Cache一致性问题(一)

    例说STM32F7高速缓存--Cache一致性问题(一) 例说STM32F7高速缓存--Cache一致性问题(二) 例说STM32F7高速缓存--Cache一致性问题(三) 为了说清楚这个问题,我特意 ...

  2. 高速缓存Cache详解(西电考研向)

    西电计组 考研笔记 内容较多 建议收藏 持续更新 欢迎关注 文章目录 高速缓存Cache详解 一.Cache概述及引入背景 二.地址映射与变换 1.全相联地址映射方式 2.直接地址映射方式 3.组相联 ...

  3. linux内核学习6:Linux的CPU高速缓存cache和页高速缓存cache,buffer

    一.CPU高速缓存(cache) 参考:https://blog.csdn.net/u014470361/article/details/80060701 参考:https://blog.csdn.n ...

  4. 计算机组成原理 学习总结3.6  Cache存储器

    3.6 Cache存储器 3.6.1 Cache基本原理 使用Cache的原因 CPU速度越来越快,主存储器与CPU的速度差距越来越大,影响CPU的工作效率. Cache的作用 在CPU和主存之间加一 ...

  5. 计算机组成原理中的直接映像,计算机组成原理cache存储器的直接映像与变换.doc...

    文档介绍: Cache存储器的直接映像与变换 1.直接映像的映像规则 在Cache存储器的直接映像中,Cache的块内地址就是主存地址格式中的块内地址,Cache的块号等于主存块号除以Cache的总块 ...

  6. c++实现高速缓存Cache

    c++实现高速缓存Cache 需求: 分析: 实现: 需求: Cache对键值对进行存储,capacity为Cache最大容量 1.get(key)方法获取对应映射值,不存在返回-1: 2.put(k ...

  7. 计算机组成原理中的直接映像,计算机组成原理--cache存储器的直接映像与变换...

    Cache存储器的直接映像与变换 1.直接映像的映像规则 在Cache存储器的直接映像中,Cache的块内地址就是主存地址格式中的块内地址,Cache的块号等于主存块号除以Cache的总块数取余.设主 ...

  8. 高速缓存cache详解

    1.(高速缓存)cache cache存在的意义:为了弥补处理器与主内存处理能力的鸿沟.硬件设计者,在处理器和主内存中引入高速缓存(cache).cache的读写速度远大于主内存.引入高速缓存后,处理 ...

  9. linux查看CPU高速缓存(cache)信息

    一.Linux下查看CPU Cache级数,每级大小 dmesg | grep cache 实例结果如下: 二.查看Cache的关联方式 在 /sys/devices/system/cpu/中查看相应 ...

  10. cache存储器最全详细介绍

    Cache基本概念和原理 cache功能 cache是一种高速缓冲存储器,是为了解决CPU和主存之间速度不匹配而采用的一项重要技术 cache原理 cache原理是基于程序运行中具有的空间局限性和时间 ...

最新文章

  1. Ubuntu14.04下安装eclipse
  2. C++中逗号操作符重载的分析
  3. (转载)Android项目实战(二十八):使用Zxing实现二维码及优化实例
  4. FastAPI ------框架基础
  5. Android Studio 插件开发详解四:填坑
  6. Zookeeper的前世今生
  7. 完美解决ArcGIS10.2和Erdas9.2软件冲突的方法:共存!
  8. Logistic Regression Classifier逻辑回归
  9. 本地仓库的基本操作与概念——Git的学习与使用(三)
  10. 我的第一个字典-Dictionary
  11. 6月9日 基于激光雷达的SLAM算法对比分析
  12. OpenCV---Canny边缘提取
  13. vue CAD-dwg格式文件预览
  14. 二、Spring AOP 切面的定义
  15. 使用python下载网络上加密的ts格式视频,并用ffmpeg进行合成
  16. 赖活不如好死?慎选你的死亡方式
  17. Java 移除List中的元素,这玩意讲究!
  18. Excel怎么将文本格式数值转换为可计算的数值型
  19. vue子路由跳转回父级,刷新部分父页面接口,push跳转
  20. BUUCTF:[GXYCTF2019]佛系青年

热门文章

  1. java 组合问题_java数组排列组合问题汇总
  2. 笔记本win10更新无线服务器,win10笔记本无线驱动升级安装图文详解
  3. 在线hash密码破解网站列表
  4. 找回git误删除的文件
  5. python爬取天眼查存入excel表格_python爬取企查查江苏企业信息生成excel表格
  6. 山大中心校区计算机课在哪,山东大学有几个校区,哪个校区最好及各校区介绍...
  7. 东南电子IPO过会:应收账款8023万 美的与格力未付款
  8. mentohust mac安装
  9. mentohust 使用
  10. 三角形面积的叉积公式