Cache-简介(第一篇)


CPU的运行速度是远远高于读写内存速度的,以当前嵌入式普遍使用的mcu来说,主频也普遍在几百Mhz,但是要知道使用的主存储器使用的动态存储器(DRAM)其存储速度在10Mhz左右。这样,如果指令和数据都存储在主存储器中,内存的速度会严重制约整个系统的性能。因此,为了解决内存速度低下,Cache就被引入了。可以说 Cache 是连接 CPU 和内存的桥梁。

在这里插入图片描述

Cache是什么

Cache全部是由硬件实现的,其不仅对于应用程序员是透明的,对系统程序员也是透明的,其是由速度与cpu速度相近的SRAM构成(Cahce和内存都是用的SRAM,那么速度为什么不同这是因为离CPU距离不同越近总线读写速度越快)。现在的处理器一般是通过多级缓存的组织形式来达到性能和功能的最优。但是其实对于多级cache还是一级cache,其原理是一致的,了解其原理后,多级和一级没有什么功能上的差异。所以我们这里以一级cache为例进行讲解。

在这里插入图片描述
单核处理器很多采用图所示的二级缓存结构。

在这里插入图片描述
多核处理器采用较多的有三级缓存结构。

1.1 时间局部性和空间局部性

Cache与主存储器之间是以Cache line(块)为基本单位进行数据交换的,整个 Cache 空间被分成 N 个 line,每个 line 通常是 32byte 或者 64byte 等, Cache line是 Cache 和内存交换数据的最小单位。当CPU读取数据或者指令时,它同时将读到的数据或者指令保存到cache line中,这样当第二次需要读取相同的数据时,它可以直接从相应的Cache中得到相应数据,由于与主存储器速度优势,这样就使用整体的性能得到里很大提高。

时间局部性
实际程序中,相邻的时间cpu访问指定内存地址的数据概率是很大的,这种规律成为时间局部性。时间局部性保证了开启cache之后,系统性能得到很大提高。
空间局部性
不同的系统中,Cache line大小也是不一样的,以32byte即8个字的cache line为例,当cpu从内存读取一个字的数据时,它会把内存中同Cache line大小相同的数据读到Cache line中。比如cpu读取地址为n的一个字,实际将n到n+31的地址中的数据都读到了cache line中。这样当cpu要读其中的数据时,可以直接通过cache获得数据。而实际的程序中,cpu访问相邻的存储空间的数据概率是很大的,这种规律称为空间局部性。

实际程序存在的时间局部性和空间局部性特征,保证了在开启cache之后,系统的性能有很大的提升。

1.2 统一的I/Dcache和独立I/Dcache

cache按照分类角度不同,可以分为不同的种类。
比如系统中如果使用的指令预期的cache和数据读写使用的cache是同一个,那么称系统使用了统一的cache。
反之,如果指令使用的cache和数据使用的cache是独立的,称为独立的cache。其中,指令预期的cache称为I-cache,数据读写的cache称为D-cache。嵌入式系统而言,目前单独的I-cache和D-cache比较多,下面也是针对这种方式来说的。
关于Cahce和内存的映射关系及其工作原理,可以参考杜春雷老师《ARM体系结构与编程》一书,这里只要了解CPU是有自己的一套机制来实现内存与缓存的对应关系即可。
需要注意的是I-cache是只读的,D-cache是读写的

1.3 写通(write-through)cache 和写回(write-back)cache

这是cache一个很重要的概念。根据CPU写cache时对内存的不同操作,可以将Cache分为两种不同的策略。

write-through(写通):
写通的策略就是指CPU每次更新cache中的内容时,Cache更新的内容也同时更新到了内存。在这种策略下,cache line
的组织结构如下所示:
在这里插入图片描述block 中存储的是内存在 Cache 缓存的数据, tag 中存储的是该 Cache line 对应的内存块
地址, valid 表示该 Cache line 中的数据是否有效(就是该cache line是否启用)。
假设处理器只有一级 Cache,当 CPU 访问一个数据时,首先会在 Cache 中寻找,第一次肯定找不到,于是就发生 Cache miss,这时内存中的数据被导入到一个 Cache line 的 block中,并将地址写到相应的 tag 位置,同时将 valid 置 1。当下一次 CPU 继续访问这个数据时,处理器根据地址在 Cache 中找到对应的 Cache line,发现 valid 标志为 1 并且 tag 标志也匹配,就直接从 Cache 中访问这个数据,这个过程叫 Cache hit。当 Cache hit 时, CPU 直接从 Cache 中访问数据,时间通常为几个周期,当 Cache miss时,数据需要从内存中导入,时间通常是几十、几百个周期。
write-back(写回):
写回的策略是指cpu更新cache的内容时,被写的数据只是写入cache,而不写入内存。而是在仅当被用于其他的内存数据(需要替换对应的cache line)时,才会将cache内容更新到内存。其组织结构过了个dirty标志,用来表示当前的cache line与内存中的数据是否是一致的,如果是一致的,dirty为0(称为 clean),如果不一致那么dirty为1。当处理器去写cache时,会将对应的cache line的dirty位置1,表示当前cache与内存数据不一致。程序运行过程中,假如其他地方需要用到同一cache line来缓存数据,那么看到这里的dirty为1,则会先将这个cache line数据更新到内存,再调入新的内存数据来使用该cache line;而如果这里的dirty为0,那么直接调用内存数据使用该cache line即可。
在这里插入图片描述写通和写回是两个很重要的概念,一般来说,一个mcu其写通和写回的区域的确定是硬件决定的。理解了valid表示当前cache line数据是否有效(是否启用),dirty表示当前cache line和内存数据是否一致后,用流程图表示下两种cache 策略的不同:
(注意:cache存在与内核与内存之间,那么无论是上述两种策略任一种,cache中的数据一定是要比内存的数据相对新的或者相同,这对于理解其处理流程很重要)

cache through流程图:
在这里插入图片描述
cache back流程图:
在这里插入图片描述
Write-through 模式的优点是操作简单;缺点是因为数据修改需要同时写入存储,数据写入速度较慢。
Write-back 模式的优点是数据写入速度快,因为不需要写存储;缺点是一旦更新后的数据未被写入存储时出现系统掉电的情况,数据将无法找回。

我们查看mcu手册可以看到其具体内存区域的cache执行策略。
下面以某设计的芯片cpu与内存之间cache关系说明:其中,non-cacheable和cacheable区分别表示是否在cpu与内存之间访问是否经过cache。其内存RAM0区域是write back策略,而RAM1为write-through策略。flash区域比较特别,其读操作属于cacheable区域,但是其擦写flash是通过flash controller借助APB总线实现的,这种方式会带来什么问题会下一章讲。

在这里插入图片描述

1.4 cache与内存的一致性问题

当引入cache后,由于cache是位于cpu与内存之间的(一定要注意cache是专属于cpu的,而外设比如DMA、UART等等与内存之间的访问是不经过cache的),因此任何外设对内存的数据修改并不能保证cache中的数据得到同样的更新;同理,cpu更新cache的修改,如果是write back这种也无法保证内存的数据是最新的。
Cache 和内存的一致性有一些是通过硬件自动保证的,另外一些则需要通过程序设计时遵守一定的规则来保证。而我们最典型的来操作内存的外设就是DMA了,因此在DMA使用时开启cache下必须要程序遵循一定规则来保证。

cache原理性的东西大致就这些,当然最重要的仍然如何解决因为是开启cache带来的一致性问题我们程序带来的烦恼。一般来说,我们遇到的一致性问题大多是write back策略的D-cache问题。
从本质上说,程序上cache带来的问题就是开启cache下,cache与内存的不一致导致我们程序上数据与执行逻辑的不一致。而具体说来,就是我们程序前后的读操作和写操作一个是操作的cache,一个操作的是内存,而两者没有同步导致的。下一节,专门讲该问题。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值