存储系统概述

计算机的存储器层级结构是越靠近CPU和CPU关系越密切价格越高容量越小,我们常见的存储器有这几种,速度从快到慢的排序是:寄存器 -> 高速缓存 -> 内存 -> 外部存储器,这一节则针对这几个存储层级进行介绍。

 

介绍完这几个常见的存储层级组件之后会介绍关于转译后备缓冲区,页面缓存,缓冲区缓存和Linux一些不常见也几乎不使用的调优参数。

 

存储组件介绍

首先我们来看看不同存储层次的介绍,包括上面提到的寄存器,高速缓存,内存以及他们三者之间的关系。

 

我们从整体上看一下存储层次结构图:

9914a490c7b84a589d9a3023172c6912.jpeg

 高速缓存:

高速缓存是位于CPU与主内存间的一种容量较小但速度很高的存储器,当内存的数据被读取之后,数据不会直接进入寄存器而是先在高速缓存进行存储,所以读取的大小取决于缓存块的大小,读取速度取决于不同层级高速缓存的容量。

 

高速缓存的执行步骤如下:

 

根据指令把数据读取到寄存器。

寄存器进行计算操作

把运算结果传输给内存

在上面的三个步骤中寄存器是基本没有传输消耗的,但是内存的传输就相对于寄存器来说就慢不少了,同时整个运算的瓶颈也是内存的传输速度,所以高速缓存就是用来解决寄存器和内存之间的巨大差异的。

 

高速缓存分为L1,L2,L3,在讲述理论知识之前,这里先举一个形象一点的例子方便理解:

 

L1 cache:就好像需要工具在我们的腰带上,可以随时取用,所以要获取它的步骤最简单也最快

L2 cache:就好像需要的工具放到工具箱里面,我们如果需要获取,要先打开工具箱然后把工具箱的工具挂到腰上才能使用,为什么不能从工具箱取出来再放回去呢?其实思考一下如果你需要频繁使用那得多累呀。另外工具箱虽然比腰上的空间大一点,但是也没有大很多,所以L2 cache 没有比L1 cache大多少。

L3 cache:L3相比L1和L2要大非常多,相当于一个仓库,我们获取数据需要自己走到仓库去找工具箱然后放到身边,然后再像是上面那样执行一次,虽然仓库容积很大,但是需要操作的步骤最多,时间开销也最大。

L1 cache下面是L2 cache,L2下面是 L3 cache,可以看到L2和L3都有跟L1 cache一样的问题,要加锁,同步,并且L2比L1慢,L3比L2慢.

 

我们假设需要读取缓存块是10个字节,高速缓存为50个字节,R0、R1的寄存器总计为20个字节,当R1需要读取某个地址的数据时,在第一次读取数据的时候将10字节先加载到高速缓存,然后再由高速缓存传输到寄存器,此时R0有10字节的数据,如果下次还需要读取10个字节,同样因为高速缓存发现缓存中有相同数据,则直接从高速缓存读取10个字节到R1中。

 

那么如果此时R0数据被改写会怎么办?首先改写寄存器值之后,会同时改写高速缓存的值,此时如果内存进来缓存块数据,在高速缓存中会先标记这些值,然后高速缓存会在某一个时刻把改写的数据同步到内存中。

 

如果高速缓存不足的情况下系统会发生什么情况?首先高速缓存会根据一些缓存淘汰机制淘汰末端最少使用的高速缓存,但是如果高速缓存的“变脏”速度很快并且高速缓存的容量总是不足的情况下,会发生内存频繁写入高速缓存并且不断变动高速缓存的情况,此时就会出现可感知的系统抖动。

 

注意本文讨论的内容全部为回写,改写的方式分为直写和回写,回写在高速缓存中存在一定的延迟,利用时间积累的方式定时改写的方式进行内存的同步刷新,而直写的方式则会在高速缓存改变的那一刻立刻改写内存的值。

那么如何衡量访问的局限性呢?

 

几乎所有的程序都可以分为下面两种情况:

 

时间局限性:在一定的时间内缓存可能被访问一次,但是可以格一小段时间再一次访问,常见的情况是一个循环中不断取值。

空间局限性:访问一段数据的同时还需要访问它周边的数据情况,有点类似磁盘的预读机制。

如果一个进程可以衡量并且把控好上面两个点,那么基本可以认为是一款优秀的程序,但是现实情况往往不是如此。

 

 

 

寄存器:

寄存器包括指令寄存器(IR)和程序计数器(PC),它属于中央处理器的组成部分,寄存器包含指令寄存器恶化程序计数器,另外在对于加减乘除的操作还包括累加器进行累加操作。 ARM走的是简单指令集不同,而X86走复杂指令集,虽然X86从现在来看是走到了尽头,但是依然发光发热并且占据市场主导地位。 复杂指令集会包含非常多的寄存器完成复杂运算,比如下面一些寄存器:

 

通用寄存器

标志寄存器

指令寄存器 当然寄存器的部分设计底层的硬件和电路原理才能了解,作者本身水都没有就不来献丑了,如果有感兴趣可以针对寄存器作为深入X86架构的入口。

内存:

内存不仅仅是我们熟知的电脑内存,从广义上来说还包括只读存储,随机存储和高速缓存存储。

 

这里可能会有疑问,为什么内存使用的最多却不如寄存器和高速缓存呢?那是因为内存不仅仅需要和CPU通信还需要和其他的控制器和硬件打交道,同时如果内存吃紧的时候CPU还需要等待内存传输,当然这也可以反过来解释为什么需要高速缓存和寄存器。

 

内存除了上面提到的这一点原因还有一个原因是主板的总线带宽是有,并且同样共享给各路使用,比如南桥和其他的一些外接设备等等,同时总线也是需要抢占的,并不是分片使用。

 

其他补充

和存储层次有关的内容之外在存储层次种还存在一些比较特殊的缓存,比如转译后备缓冲区和页面缓存,

 

转译后备缓冲区

下面的内容来自百科的解释:

 

转译后备缓冲器(英语:Translation Lookaside Buffer,首字母缩略字:TLB),通常也被称为页表缓存、转址旁路缓存,为CPU的一种缓存,由内存管理单元用于改进虚拟地址到物理地址的转译速度。目前所有的桌面型及服务器型处理器(如 x86)皆使用TLB。TLB具有固定数目的空间槽,用于存放将虚拟地址映射至物理地址的标签页表条目。为典型的结合存储(content-addressable memory,首字母缩略字:CAM)。其搜索关键字为虚拟内存地址,其搜索结果为物理地址。如果请求的虚拟地址在TLB中存在,CAM 将给出一个非常快速的匹配结果,之后就可以使用得到的物理地址访问存储器。如果请求的虚拟地址不在 TLB 中,就会使用标签页表进行虚实地址转换,而标签页表的访问速度比TLB慢很多。有些系统允许标签页表被交换到次级存储器,那么虚实地址转换可能要花非常长的时间。

 

进程如果想要访问特殊的数据,可以通过下面提到的方式访问逻辑地址:

 

对照物理页表通过查表的方式把虚拟地址转物理地址

通过访问对应的物理地址寻找实际的物理地址

如果你是C语言相信应该挺熟悉的,没错这里的操作类似一个二级指针的访问操作,可以看到如果想要高速缓存发挥作用必须是一级指针的查找才有意义。但是二级指针的查找是没有太大意义的。

 

所以TLB的作用就是这么来的,转译后备缓冲器说白了就是用于加速虚拟地址到物理地址转化的一块特殊空间。目的是为了提高多级嵌套映射查找的速度。

 

页面缓存

注意上面提到的内容是页表缓存,这里是页面缓存。

 

页面缓存的作用是什么呢?我们都知道外部的硬件存储速度是最为缓慢的,通常应用程序操作硬盘中的数据都是预先把数据加载到内存再进行操作,然而数据并不是直接从磁盘拷贝到内存的,而是在内存和外部存储设备之间多了一层页面缓存。 页面缓存的读取步骤如下:

 

进程读取磁盘文本数据,寻找到相关数据之后将内容加载到页面缓存

把页面缓存的内容复制到内存中,此时物理数据和内存以及页面缓存数据一致。

如果需要改写文件文本数据,首先会通知页面缓存标记自己为“脏页”。

如果内存不足则空出空闲的页面缓存给内存使用。

如果页面缓存和内存都不足就需要刷新“脏页”空出空间给内存继续使用。

通常情况下页面缓存会定期刷新缓存回写到磁盘中保持数据同步。

另外需要注意如果页面缓存一直没有进程访问或者使用,页面缓存会一直“膨胀”,另外如果页面缓存和内存一直不够用,就会不断的回写脏页并且产生性能抖动问题。

 

通过这一点我们也可以知道为什么不建议电脑开很多的应用程序。因为如果如果发生页面缓存回收会产生操作系统用户可以感知的抖动问题。

 

缓冲区缓存

缓冲区缓存很容易和页面缓存搞混,我们只需要简单理解是对原始磁盘块的临时存储,也就是用来缓存磁盘的数据,通常出现在设备文件直连外部的存储设备,比如我们的U盘读写和外接磁盘的读写等等,这些读写通过缓存区缓存进行管理。

 

需要注意缓冲区缓存通常不会特别大(20MB 左右),这样内核就可以把分散的写集中起来,统一优化磁盘的写入,比如可以把多次小的写合并成单次大的写等等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值