第六章 存储器层次结构

存储器层次结构

6.1 存储技术
6.2 局部性
6.3 存储器层次结构
6.4 高速缓存存储器
6.5 编写高速缓存友好的代码
6.7 小结
6.8 关于磁盘的补充讲解

       好的程序代码不仅要有好的算法,对计算机硬件的充分利用也是很关键的一步。

       存储器系统(memorysystem)是一个具有不同容量、成本和访问时间的存储设备的层次结构。CPU寄存器保存着最常用的数据。靠近CPU的小的、快速的高速缓存存储器(cache memory)作为一部分存储在相对慢速的主存储器(mainmemory,简称主存)中的数据和 指令的缓冲区域。主存暂时存放存储在容量较大的、慢速磁盘上的数据,而这些磁盘常常又作为存储在通过网络连接的其他机器的磁盘或磁带上的数据的缓冲区域。

       一般来说,如果你的程序需要的数据是存储在CPU寄存器中的,那么在指令的执行期间,在零个周期内就能访问到它们。如果存储在高速缓存中,需要1〜30个周期。如果存储在主存中,需要50〜200个周期。而如果存储在磁盘上,需要大约几千万个周期

6.1存储技术

6.1.1 随机访问存储器

       随机访问存储器(Random-AccessMem)分为两类:静态的和动态的。静态RAM (SRAM)

       比动态RAM(DRAM)更快,但也贵得多。SRAM用来作为高速缓存存储器,既可以在CPU芯片上,也可以在片下。

静态存储器

       SRAM将每个位存储在一个双稳态的(bitable)存储器单元里。每个单元是用一个六晶体管电路来实现的。

动态RAM

       DRAM将每个位存储为对一个电容的充电。这个电容非常小,通常只有大约30毫微微法拉 (femtofarad)——30*10^15法拉。不过,回想一下法拉是一个非常大的计量单位。DRAM存储 器可以制造得非常密集——每个单元由一个电容和一个访问晶体管组成。


非易失性存储器

       如果断电,DRAM和SRAM会丢失它们的信息,从这个意义上说,它们是易失的(volatile)。另一方面,非易失性存储器(nonvolatilememory)即使是在关电后,也仍然保存着它们的信息。

       PROM (Programmable ROM,可编程ROM)只能被编程一次。PROM的每个存储器单元有一种熔丝(fUse),它只能用高电流熔断一次。可擦写可编程ROM (Erasable Programmable ROM, EPROM)有一个透明的石英窗口,允许 光到达存储单元。EPROM能够被擦除和重编程的次数的数量级可 以达到 1000 次。电子可擦除 PROM (Electrically Erasable PROM, EEPROM)类似于 EPROM,但是它不需要一个物理上独立的编程设备,因此可以直接在印制电路卡上编程。EEPROM能够 被编程的次数的数量级可以达到105次。闪存(flash memory)是一类非易失性存储器,基于EEPROM,它已经成为了一种重要的存储技术。

访问主存

        数据流通过称为总线(bus)的共享电子电路在处理器和DRAM主存之间来来回回。每次CPU和主存之间的数据传送都是通过一系列步骤来完成的,这些步骤称为总线事务(bustransaction)0 读事务(read transaction)从主存传送数据到 CPU。写事务(write transaction)从CPU传送数据到主存。


IO桥是将系统总线的电子信号翻译成存储器总线的电子信号。


6.1.2 磁盘存储

       磁盘是由盘片(platter)构成的。每个盘片有两面或者称为表面(surface),表面覆盖着磁性记录材料。盘片中央有一个可以旋转的主轴(spindle),它使得盘片以固定的旋转速率 (rotational rate)旋转,通常是 5400〜15000 转每分钟(Revolution Per Minute, RPM)0磁盘通常包含一个或多个这样的盘片,并封装在一个密封的容器内。

      一个典型的磁盘表面的结构。每个表面是由一组称为磁道(track)的同心圆组成的。每个磁道被划分为一组扇区(sector)。每个扇区包含相等数量的数据位(通常是512字 节),这些数据编码在扇区上的磁性材料中。扇区之间由一些间隙(gap)分隔开,这些间隙中不存储数据位。间隙存储用来标识扇区的格式化位。


        磁盘有一个或多个叠放在一起的盘片组成,他们被封装在一个密闭的包装里,如上图的(b)所示,整个装置称为磁盘驱动器,我们简称磁盘。SSD(固态硬盘是没有移动的部分的)。

磁盘容量:


磁盘操作:

        盘用读/写头(read/write head)来读写存储在磁性表面的位,而读写头连接到一个传动臂(actuator arm) —端,如图6-10a所示。通过沿着半径轴前后移动这个传动臂,驱动器可以将 读/写头定位在盘面上的任何磁道上。这样的机械运动称为寻道(seek)。一旦读/写头定位到了 期望的磁道上,那么当磁道上的每个位通过它的下面时,读/写头可以感知到这个位的值(读该位),也可以修改这个位的值(写该位)。有多个盘片的磁盘针对每个盘面都有一个独立的读/写头,如图6-10b所示。读/写头垂直排列,一致行动。在任刻,所有的读/写头都位于同一个柱面上。


        磁盘以扇区大小的块来读写数据。对扇区的访问时间(access time)主要有三个部分:寻道时间(seek time)、旋转时间(rotational time)和传送时间(transfer time)。

访问磁盘:


        在磁盘控制器接收到CPU的读命令后,它将逻辑号翻译成一个扇区地址,读该扇区的内容,然后将这些内容直接传送到主存,不需要CPU的干涉,这个过程称为直接存储器传送(Direct Memory Access, DMA),这种数据传送称为DMA传送

6.1.3 固态硬盘

       固态硬盘(Solid State Disk, SSD)是一种基于闪存的存储技术


6.2 局部性

    一个编写良好的计算机程序常常具有良好的局部性(locality)。也就是说,它们倾向于引用 邻近于其他最近引用过的数据项的数据项,或者最近引用过的数据项本身。这种倾向性,被称为 局部性原理(principle of locality),是一个持久的概念,对硬件和软件系统的设计和性能都有着 极大的影响。

        局部性通常有两种不同的形式:时间局部性(temporal locality)和空间局部性(spatial locality)。在一个具有良好时间局部性的程序中,被引用过一次的存储器位置很可能在不远的将来再被多次引用。在一个具有良好空间局部性的程序中,如果一个存储器位置被引用了一次,那 么程序很可能在不远的将来引用附近的一个存储器位置。

局部性小结:

        在这一节中,我们介绍了局部性的基本思想,还给出了一些量化评价一个程序中局部性的简单原则

        •重复引用同一个变量的程序有良好的时间局部性。

         •对于具有步长为t的引用模式的程序,步长越小,空间局部性越好。具有步长为1的引 用模式的程序有很好的空间局部性。在存储器中以大步长跳来跳去的程序空间局部性会很差。

         •对于取指令来说,循环有好的时间和空间局部性。循环体越小,循环迭代次数越多,局部性越好。

6.3 存储器层次结构


6.3.1 存储器层次结构中的缓存

       数据块总是以块大小为传送单位(transfer unit)在第k层和第k+1层之间来回拷贝。



6.4 高速缓存存储器


6.4.1 通用的高速缓存存储器结构



3种方式的高速缓存

       直接映射高速缓存(每组一行,即E=1)

       组相联高速缓存

       全相联高速缓存

6.4.2 直接映射高速缓存

        根据E(每个组的高速缓存行数)高速缓存被分为不同的类。每个组只有一行(E=1)的高速缓存称为直接映射高速缓存(direct-mapped cache)。

直接映射高速缓存中的组选择


直接映射高速缓存中的行匹配

       当且仅当设置了有效位,而且高速缓存中的标记与w的地址中的标记相匹配时,这一行包含w的一个拷贝。

直接映射高速缓存中的字选择


直接映射高速缓存的冲突不命中

产生抖动问题:即高速缓存反复加载和驱逐相同的高速缓存块的组(原因,引用的块被映射到同一个高速缓存组),

解决方法:在每个数组的结尾放B字节的填充,例如将原本的float x[8]定义成 float x[12],即消除了抖动不命中。

为什么用中间的位来作为索引


6.4.3 组相联高速缓存

        组相联高速缓存(setassociative cache)放松了在直接映射高速缓存中E=1的限制,所以每个组都可以保存有多于一个的高速缓冲行。一个1<E<C/B的高速缓冲行称为E路相联高速缓冲。


上图是一个2路组相联高速缓冲行的特例…….

6.4.4 全相联高速缓存

       一个全相联高速缓存(fullyassociative cache)是由一个包含所有高速缓存行的组(即E=C/B)组成的。

全相联高速缓存中的组选择


6.4.5 有关写的问题

       高速缓存关于读的操作非常简单,首先,在高速缓存中查找所需子w的拷贝。如果命中,则立即返回给CPU。如果不命中,则从存储器结构中较低层中取出包含字w的块,将这个块存储到某个行中(可能会驱逐一个有效行),然后返回字w。

        写的情况就要复杂一些了。假设我们要写一个已经缓存了的字w写命中(write hit)。在高速 缓存更新了它的w的拷贝之后,怎么更新w在层次结构中紧接着低一层中的拷贝昵?最简单的 方法,称为直写(write-through),就是立即将w的高速缓存块写回到紧接着的低一层中。虽然 简单,但是直写的缺点是每次写都会引起总线流量。另一种方法,称为写回(write-back),尽可 能地推迟存储器更新,只有当替换算法要驱逐更新过的块时,才把它写到紧接着的低一层中。由 于局部性,写回能显著地减少总线流量,但是它的缺点是增加了复杂性。高速缓存必须为每个高 速缓存行维护一个额外的修改位(dirtybit),表明这个髙速缓存块是否被修改过。

        另一个问题是如何处理写不命中。一种方法称为写分配(write-allocate),加载相应的低一 层中的块到高速缓存中,然后更新这个高速缓存块。写分配试图利用写的空间局部性,但是缺点是每次不命中都会导致一个块从低一层传送到高速缓存。另一种方法,称为非写分配(not-write-allocate),避开高速缓存,直接把这个字写到低一层中。直写高速缓存通常是非写分配的。写回高速缓存通常是写分配的。

        一般而言,高速缓存越往下层,越可能采用写回而不是直写。

6.4.6 一个真是的高速缓存层次结构的解析

        实际上,高速缓存既可以保存数据也可以保存指令。只保存指令的高速缓存称为i-cache,只保存程序数据的高速缓存称为d-cache。记保存数据又保存指令的高速缓存称为统一的高速缓存(unified cache)。



6.5  编写高速缓存友好的代码

    一般高速缓存友好的基本方法:

    1让常见的情况运行的快。程序通常把大部分时间都花在少量的核心函数上,而这些函数通常把时间都花在了少量循环上。所以集中注意力在核心函数的少量循环上,而忽略其他部分。

    2在每一个循环内部缓存不命中的数量最小。


6.6 综合:高速缓存对程序性能的影响

        理解存储器层次结构本质的程序员能够利用这些知识编写出更有效的程序,无论具体的存储系统结构是怎样的。特别地,我们推荐下列技术:

        ·将你的注意力集中在内循环上,大部分计算和存储器访问都发生在这里。

        ·通过按照数据对象存储在存储器中的顺序、以步长为1的来读数据,从而使得你程序中的 空间局部性最大。

        ·一旦从存储器中读入了一个数据对象,就尽可能多地使用它,从而使得程序中的时间局部 性最大。


6.7 小结

         基本存储技术包括随机存储器(RAM)、非易失性存储器(ROM)和磁盘。RAM有两种基 本类型。静态RAM (SRAM)快一些,但是也贵一些,它既可以用做CPU芯片上的高速缓存, 也可以用做芯片下的高速缓存。动态RAM (DRAM)慢一些,也便宜一些,用做主存和图形帧缓冲区。非易失性存储器,也称为只读存储器(ROM),即使是在关电的时候,也能保持它们的 信息,它们用来存储固件。旋转磁盘是机械的非易失性存储设备,以每个位很低的成本保存大量的数据,但是访问时间比DRAM更长。固态硬盘(SSD)基于非易失性的闪存,越来越变成旋转磁盘对某些应用的具有吸引力的替代产品。

        一般而言,较快的存储技术每个位的价格会更高,而且容量较小。这些技术的价格和性能属性正在以显著不同的速度变化着。特别地,DRAM和磁盘访问时间远远大于CPU周期时间。 系统通过将存储器组织成存储设备的层次结构来弥补这些差异,在这个层次结构中,较小、较 快的设备在顶部,较大、较慢的设备在底部。因为编写良好的程序有好的局部性,大多数数据都可以从较高层得到服务,结果就是存储系统能以较高层的速度运行,但却有较低层的成本和 容量。

        程序员可以通过编写有良好空间和时间局部性的程序来显著地改进程序的运行时间。利用基于SRAM的高速缓存存储器特别重要。主要从高速缓存取数据的程序能比主要从存储器取数据的程序运行得快得多

6.8 关于磁盘的补充讲解

---------------------------------------------------------------------------------------------------------------------

        总的来说,磁盘结构包括:盘片、磁头、盘片主轴、控制电机、磁头控制器、数据转换器、接口、缓存等。一般一个磁盘就一个主轴。 一般每个扇区的大小为512B


硬盘上的盘片是如何进行分区的、有哪几种分区、如何存储分区信息的?      

磁盘的分区

         装过系统的人都知道必须要分区后才能安装系统,形象点的说比如windows里C:,D:之类的东西;如果你要问硬盘为什么要分区,我也说不上来很严格的原因,首先从使用习惯上来讲,我们不希望数据杂乱无章堆积在一起,其次,如果不分区,如何才能在一块硬盘上使用不同的文件系统(下面讲到)呢,学院派的说法是:数据安全和性能考虑。

先要说硬盘中最最重要的第一扇区,因为整块硬盘的重要信息都在这里:

MBR(Master Boot Record 主启动记录)开机引导程序就在安装在此,占用446byte;

DPT(Disk Partition table 硬盘分区表)记录硬盘上的分区元信息,占用64byte。

        MBR是如何工作的呢,不用深究,反正就是系统开始时会主动读取数据的地方,这样才能引导进行操作系统的启动;

        DPT要仔细的讲讲,分区的大致意思就如同抢地盘,不过人家比较规矩,按照柱面(最小的分区单位)分配,比如第一个分区从柱面1-200,第二个分区201-500,但三个分区501-1000...(省略并非可以无限分配下去哦)



         为啥说不能一直分配下去呢,技术柱面数量足够,因为上面说到硬盘分区表只有64个字节,每条分区记录需要占用16字节,最多只能分4个,疑问在此:我的电脑怎么分了5个(c\d\e\f\g)?

         其实我说的4个分区是所谓的主分区,为了能支持很多分区引入了扩展分区的概念, 也就是说,可以使用DPT中一条记录来记录扩展分区的信息,然后在扩展分区中再继续划分逻辑分区,而逻辑分区的分区信息则记录在扩展分区的第一个扇区中,如此则可以像链表一样划分出很多分区来。但注意,一个分区表中可以有1~4条主分区,但是最多只能有1个扩展分区 

        分区表之间是如何关联的,详细讲一下,分区表是一个单向链表,第一个分区表,也就是位于硬盘第一个扇区中的DPT,可以有一项记录扩展分区的起始位置柱面,类似于指针的概念,指向扩展分区(图3),根据这项记录我们可以找到扩展分区的某柱面0磁头1扇区(CHS),而这个扇区中又存放了第二个分区表,第二个分区表第一项记录一般表述了当前所在的逻辑分区的起始/终止柱面,第二项记录表述了下一个逻辑分区所在的0磁头1扇区(CHS),第三、第四项记录不存任何信息(图4)。

        请看下图,主引导记录/分区表所在的是硬盘第一个分区,基本分区1、基本分2、基本分区3都是主分区、扩展分区内有2个逻辑分区,每个逻辑分区的第一个扇区都是分区表。

分区表中以0x55AA为结束符

分区后的系统启动

之前提到MBR中安装的引导加载程序,他的作用是什么?

①      提供开机菜单选项:可以供用户选择启动哪个操作系统,这是多重引导功能。

②      加载操作系统内核:每个操作系统都有自己的内核,需要引导程序来加载

③      转交给其他引导程序:可以将工作移交给其他引导程序来进行上述操作。


        其实引导加载程序除了可以安装在MBR中,还可以直接安装在每个分区的引导扇区(DBR)中,注意下,每个分区(主分区、逻辑分区)都有一个自己的启动扇区,专门用来安装引导加载程序,如上图表3。

系统启动过程:

①    首先,BIOS启动后,读取硬盘第一个扇区MBR中的引导加载程序(可能是windows或者linux的grub)

②    MBR中的引导程序提供开机菜单,你可以选择1)直接加载windows 内核 2)将工作转交给windows分区内的引导扇区中的加载程序,让他自己去加载内核 3)转交给linux分区内引导扇区,让他去加载linux.

③    根据用户选择的选项和引导加载程序中记录的分区,到分区表找对应的分区柱面号等分区信息,启动内核或者分区加载程序。

        Window安装时默认会自动将MBR和windows所在分区的引导扇区都装上引导程序,而不会提供任何选项给用户选择,因此如果之前装过其他操作系统,然后再另外装一个         windows时,会把公用的MBR覆盖掉,如此,原来的操作系统就无法启动了。如果先装windows,然后装linux,linux 会覆盖MBR,然后让用户选择是否将windows等其他操作系统的启动项添加进来,如果你选择了添加进来,那么你在开机时就会有两个选项让用户进行选择了。

文件系统

        文件系统也是很大很复杂的话题,我们仍然以比较通俗、粗颗粒度来讲解,试想一下,我们的文件如何对应到磁盘的扇区上呢,所以光有底层的概念 磁道 扇区是没有用的,需要更加抽象的数据类型或结构来抽象底层的细节。

        文件系统是一套实现了数据的存储、分级组织、访问和获取等操作的抽象数据类型(Abstract data type)。

        文件系统是一种用于向用户提供底层数据访问的机制。它将设备中的空间划分为特定大小的块(扇区),一般每块512字节。数据存储在这些块中,大小被修正为占用整数个块。由文件系统软件来负责将这些块组织为文件和目录,并记录哪些块被分配给了哪个文件,以及哪些块没有被使用。

        不过,文件系统并不一定只在特定存储设备上出现。它是数据的组织者和提供者,至于它的底层,可以是磁盘,也可以是其它动态生成数据的设备(比如网络设备)

---------------------------------------------------------------------------------------------------------------------

参考资料:

1、《深入理解计算机系统》的第6章 存储器层次结构

2、网上资料,硬盘基础知识 - http://www.cnblogs.com/shishm/archive/2011/10/24/2222469.html

猜你喜欢

转载自blog.csdn.net/weixin_41413441/article/details/79447977