主存和cache每一块相等_CPU中的Cache实现原理

本文翻译自:http://duartes.org/gustavo/blog/
微信公众号:技术原理君

3117f33a60f34ccb313449f9fbfc40ef.png

本文简要的展示了现代Intel处理器的CPU cache是如何组织的。有关cache的讨论往往缺乏具体的实例,使得一些简单的概念变得扑朔迷离。也许是我可爱的小脑瓜有点迟钝吧,但不管怎样,至少下面讲述了故事的前一半,即Core 2的 L1 cache是如何被访问的:

8b6a441792424c01f524f6ab1e388613.png

L1 cache – 32KB,8路组相联,64字节缓存线

1. 由索引拣选缓存组(行)

在cache中的数据是以缓存线(line)为单位组织的,一条缓存线对应于内存中一个连续的字节块。这个cache使用了64字节的缓存线。这些线被保存在cache bank中,也叫(way)。每一路都有一个专门的目录(directory)用来保存一些登记信息。你可以把每一路连同它的目录想象成电子表格中的一列,而表的一行构成了cache的一(set)。列中的每一个单元(cell)都含有一条缓存线,由与之对应的目录单元跟踪管理。图中的cache有64 组、每组8路,因此有512个含有缓存线的单元,合计32KB的存储空间。

在cache眼中,物理内存被分割成了许多4KB大小的物理内存页(page)。每一页都含有4KB / 64 bytes == 64条缓存线。在一个4KB的页中,第0到63字节是第一条缓存线,第64到127字节是第二条缓存线,以此类推。每一页都重复着这种划分,所以第0页第3条缓存线与第1页第3条缓存线是不同的。

全相联缓存(fully associative cache)中,内存中的任意一条缓存线都可以被存储到任意的缓存单元中。这种存储方式十分灵活,但也使得要访问它们时,检索缓存单元的工作变得复杂、昂贵。由于L1和L2 cache工作在很强的约束之下,包括功耗,芯片物理空间,存取速度等,所以在多数情况下,使用全相联缓存并不是一个很好的折中。

取而代之的是图中的组相联缓存(set associative cache)。意思是,内存中一条给定的缓存线只能被保存在一个特定的组(或行)中。所以,任意物理内存页的第0条缓存线(页内第0到63字节)必须存储到第0组,第1条缓存线存储到第1组,以此类推。每一组有8个单元可用于存储它所关联的缓存线(译注:就是那些需要存储到这一组的缓存线),从而形成一个8路关联的组(8-way associative set)。当访问一个内存地址时,地址的第6到11位(译注:组索引)指出了在4KB内存页中缓存线的编号,从而决定了即将使用的缓存组。举例来说,物理地址0x800010a0的组索引是000010,所以此地址的内容一定是在第2组中缓存的。

但是还有一个问题,就是要找出一组中哪个单元包含了想要的信息,如果有的话。这就到了缓存目录登场的时刻。每一个缓存线都被其对应的目录单元做了标记(tag);这个标记就是一个简单的内存页编号,指出缓存线来自于哪一页。由于处理器可以寻址64GB的物理RAM,所以总共有64GB / 4KB == 224个内存页,需要24位来保存标记。前例中的物理地址0x800010a0对应的页号为524,289。下面是故事的后一半:

04c00f15600d07515fccb836e8ca9e54.png

在组中搜索匹配标记

由于我们只需要去查看某一组中的8路,所以查找匹配标记是非常迅速的;事实上,从电学角度讲,所有的标记是同时进行比对的,我用箭头来表示这一点。如果此时正好有一条具有匹配标签的有效缓存线,我们就获得一次缓存命中(cache hit)。否则,这个请求就会被转发的L2 cache,如果还没匹配上就再转发给主系统内存。通过应用各种调节尺寸和容量的技术,Intel给CPU配置了较大的L2 cache,但其基本的设计都是相同的。比如,你可以将原先的缓存增加8路而获得一个64KB的缓存;再将组数增加到4096,每路可以存储256KB。经过这两次修改,就得到了一个4MB的L2 cache。在此情况下,需要18位来保存标记,12位保存组索引;缓存所使用的物理内存页的大小与其一路的大小相等。(译注:有4096组,就需要lg(4096)==12位的组索引,缓存线依然是64字节,所以一路有4096*64B==256KB字节;在L2 cache眼中,内存被分割为许多256KB的块,所以需要lg(64GB/256KB)==18位来保存标记。)

如果有一组已经被放满了,那么在另一条缓存线被存储进来之前,已有的某一条则必须被腾空(evict)。为了避免这种情况,对运算速度要求较高的程序就要尝试仔细组织它的数据,使得内存访问均匀的分布在已有的缓存线上。举例来说,假设程序中有一个数组,元素的大小是512字节,其中一些对象在内存中相距4KB。这些对象的各个字段都落在同一缓存线上,并竞争同一缓存组。如果程序频繁的访问一个给定的字段(比如,通过虚函数表vtable调用虚函数),那么这个组看起来就好像一直是被填满的,缓存开始变得毫无意义,因为缓存线一直在重复着腾空与重新载入的步骤。在我们的例子中,由于组数的限制,L1 cache仅能保存8个这类对象的虚函数表。这就是组相联策略的折中所付出的代价:即使在整体缓存的使用率并不高的情况下,由于组冲突,我们还是会遇到缓存缺失的情况。然而,鉴于计算机中各个存储层次的相对速度,不管怎么说,大部分的应用程序并不必为此而担心。

一个内存访问经常由一个线性(或虚拟)地址发起,所以L1 cache需要依赖分页单元(paging unit)来求出物理内存页的地址,以便用于缓存标记。与此相反,组索引来自于线性地址的低位,所以不需要转换就可以使用了(在我们的例子中为第6到11位)。因此L1 cache是物理标记但虚拟索引的(physically tagged but virtually indexed),从而帮助CPU进行并行的查找操作。因为L1 cache的一路绝不会比MMU的一页还大,所以可以保证一个给定的物理地址位置总是关联到同一组,即使组索引是虚拟的。在另一方面L2 cache必须是物理标记和物理索引的,因为它的一路比MMU的一页要大。但是,当一个请求到达L2 cache时,物理地址已经被L1 cache准备(resolved)完毕了,所以L2 cache会工作得很好。

最后,目录单元还存储了对应缓存线的状态(state)。在L1代码缓存中的一条缓存线要么是无效的(invalid)要么是共享的(shared,意思是有效的,真的J)。在L1数据缓存和L2缓存中,一条缓存线可以为4个MESI状态之一:被修改的(modified),独占的(exclusive),共享的(shared),无效的(invalid)。Intel缓存是包容式的(inclusive):L1缓存的内容会被复制到L2缓存中。在下一篇讨论线程(threading),锁定(locking)等内容的文章中,这些缓存线状态将发挥作用。下一次,我们将看看前端总线以及内存访问到底是怎么工作的。这将成为一个内存研讨周。

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

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

相关文章

玩转oracle 11g(21):修改为静态监听

4. listener修改为静态监听 增加红色部分 SID_LIST_LISTENER (SID_LIST (SID_DESC (SID_NAME PLSExtProc) (ORACLE_HOME d:\oracle\product\10.2.0\db_1) (PROGRAM extproc) ) (SID_DESC (GLOBAL_DBNAME docare) (ORACLE_H…

Python+Selenium练习篇之2-利用ID定位元素

在前面一篇文章,我们介绍了如何摘取页面字段,通过正则进行匹配符合要求的字段。如果感觉有点困难,不能立马理解,没有关系。把字符串摘取放到第一篇,是因为自动化测试脚本,经常要利用字符串操作,…

玩转oracle 11g(22):ora-01691和修改密码过期时间

5. 增加新的数据文件 报:ORA -01691错误 解决描述: 在对应表空间增加新的数据文件 1. select * from dba_data_files ; 查询出表空间的数据文件路径 2.通过语句增加:举例:表空间TSP_MEDSURGERY alter tablespace TSP_MEDSURGER…

华为云上可订阅F5_F5亮相华为云计算大会 解读云应用交付

全球领先的应用交付网络厂商F5 Networks, Inc.(NASDAQ: FFIV)在下周于上海召开的2012华为云计算大会上向用户呈现其面向云计算的应用交付解决方案。在本次活动中,F5将重点为用户展示与华为在云计算方面的合作,F5与华为的联合解决方案如何帮助企业部署云架…

1. 栈和队列的数组实现

栈和队列的比较 栈和队列都属于线性表,且在其上进行Insert和Delete操作所插入和移除的元素是预先设定的。在栈中,在一端插入,在同一端删除,位于该端点的元素称为栈顶元素;在队列中,在一端插入,在…

玩转oracle 11g(23):区分大小写和字符集不同

7. 11g默认开始密码区分大小写 可以通过把参数设置为 SEC_CASE_SENSITIVE_LOGON FALSE 屏蔽 alter system set SEC_CASE_SENSITIVE_LOGON FALSE scopeboth; 8. 字符集不同 Database character set (AL32UTF8) and Client character set (ZHS16GBK) are different. Character…

树莓派4b装系统_树莓派4B初次使用--系统安装|配置

准备硬件:树莓派本体、读卡器、TF卡、电源线、HDMI连接线(可选)、显示器(可选)软件:SDFormatter格式化工具、Win32DiskImager烧录工具、Finalshell、Cellular-Z技术规格首先,来看看树莓派4的外形,和之前的树莓派3差别不大&#xf…

IntelliJ IDEA——提交代码到GitHub远程库

记录一下在IDEA上怎样将写的代码提交到GitHub远程库: 下面这个图是基本的提交代码的顺序: 将代码Add到stage暂存区 本地修改了代码后,需先将代码add到暂存区,最后才能真正提价到git仓库。 首先,IDEA中,选中…

玩转oracle 11g(24):数据文件设置自扩展和监听日志文件过大处理

10. 数据文件为打开自动扩展 select * from dba_data_files; 查询结果: AUTOEXTENSIBLE MAXBYTES MAXBLOCKS INCREMENT_BY NO 0 0 0 NO 0 0 0 NO 0 …

安装mysql5.6.10_windows下安装mysql(mysql-installer-community-5.6.10.1)详细教程

一、安装前的准备1、下载安装程序包,可到MySQL官方网站www.mysql.com下载,如图1-1:图1-1下载后的安装文件如图1-2所示:图1-2二、安装1、双击下载的安装文件,本篇博文安装的MySQL版本为5.6.10.1,出现如图1-3…

往事不堪回首

UPD:2018/10/9 第一次墙外调查:立个Flag吧!第100场,上红! 哈哈哈哈哈哈哈哈哈哈! 妙啊! UPD:2018/10/23 第二次墙外调查:下一场,要不要试着把橙名第二段击穿呢…

玩转oracle 11g(25):手工删除oracle归档日志后操作步骤 和修改用户默认解锁时间

12.手工删除oracle归档日志后操作步骤 1. 开始-》运行-》cmd 2.cmd-> set oracle_siddocare 3.cmd-> rman target / 如果报错:ORA-12560: TNS: 协议适配器错误 安装32bit客户端造成 直接输入: rman target system/docaredocare 4. 将归档日…

mysql 索引计划_Mysql索引、查询计划、优化方向

索引Innodb索引(聚集索引)(聚簇表分布)Innodb是索引组织表,其结构是BTree。其表索引结构是聚簇表分布。其叶子节点保存了KeyRow Data(聚集索引,按主键排序),其Key是主键或非空的唯一索引。而其二级索引是非主键或者非空的唯一索引。即Innodb表…

[复习]莫比乌斯反演,杜教筛,min_25筛

[复习]莫比乌斯反演,杜教筛,min_25筛 莫比乌斯反演 做题的时候的常用形式:\[\begin{aligned}g(n)&\sum_{n|d}f(d)\\f(n)&\sum_{n|d}\mu(\frac{d}{n})g(d)\end{aligned}\] 实际上还有\[\begin{aligned}g(n)&\sum_{d|n}f(d)\\f(n)&\sum_{d|n}\mu(\fra…

玩转oracle 11g(26):误删表数据和误删表回滚

14.误删除表中数据并提交(deletecommit) select * from med_dept_dict as of timestamp sysdate - 1/1440 描述:其中med_dept_dict 为误删除数据的表 sysdate - 10/1440 表示查询10分钟之前数据 注意:数据来源是查询undo中的撤…

mysql kingshard 扩容_如何用Go打造一个高性能mysql proxy

kingshard架构设计和功能实现kingshard(https://github.com/flike/kingshard)开源有一段时间了,有些热心的用户发邮件来咨询kingshard的设计和实现问题。于是周末抽空写了一篇介绍kingshard架构和功能实现的文章,希望通过本文能够让用户对kingshard有更深…

玩转oracle 11g(27):ora-12154和客户端版本低

16. 64bit windows操作系统上 安装了32bit的oracle alert log 里不断的出现如下错误: OER 7451 in Load Indicator : Error Code OSD-04500: illegal option specified O/S-Error: (OS 1) 函数不正确。! 每10秒出现一次错误提示。 解决方案: 重新安装or…

mysql 命令行 主从复制_MySQL 的主从复制(高级篇)

首先要明白为什么要用 mysql 的主从复制:1–在从服务器可以执行查询工作 (即我们常说的读功能),降低主服务器压力;(主库写,从库读,降压)2–在从主服务器进行备份,避免备份期间影响主服务器服务;…

方法的重写

方法的重写 1、在子类中可以根据需要对从基类中继承的方法进行重写 2、重写方法必须和被重写方法具有相同对的方法名称,相同的参数列表和返回值类型 3、重写方法不能使用比被重写方法更严格的访问权限 在方法重写的时候注意:对那个方法进行重写尽量copy那…

[Android]安装 Android Studio 第一行Android代码

安装 Android Studio 1.下载 官网 建议官网下载https://developer.android.com/index.html 网盘 链接:https://pan.baidu.com/s/1b8KyEMYbSYt9EQJ2e8Ge6w 提取码:ytn4 《第一行代码》第二版提供版本(2016年) 2.安装组件全…